feat(http): added params parameter

The params parameter can now be used to serialize parameters in the URLs. The serialization does proper escaping and JSON encoding if it is an object.
This commit is contained in:
Misko Hevery 2012-03-23 13:41:48 -07:00
parent ac75079e21
commit 73c8593077
2 changed files with 46 additions and 6 deletions

View file

@ -1,4 +1,5 @@
'use strict';
'use strict';
/**
* Parse headers into key value object
@ -360,6 +361,8 @@ function $HttpProvider() {
*
* - **method** `{string}` HTTP method (e.g. 'GET', 'POST', etc)
* - **url** `{string}` Absolute or relative URL of the resource that is being requested.
* - **params** `{Object.<string|Object>}` Map of strings or objects which will be turned to
* `?key1=value1&key2=value2` after the url. If the value is not a string, it will be JSONified.
* - **data** `{string|Object}` Data to be sent as the request message data.
* - **headers** `{Object}` Map of strings representing HTTP headers to send to the server.
* - **transformRequest** `{function(data, headersGetter)|Array.<function(data, headersGetter)>}`
@ -638,7 +641,8 @@ function $HttpProvider() {
var deferred = $q.defer(),
promise = deferred.promise,
cache,
cachedResp;
cachedResp,
url = buildUrl(config.url, config.params);
$http.pendingRequests.push(config);
promise.then(removePendingReq, removePendingReq);
@ -649,7 +653,7 @@ function $HttpProvider() {
}
if (cache) {
cachedResp = cache.get(config.url);
cachedResp = cache.get(url);
if (cachedResp) {
if (cachedResp.then) {
// cached request has already been sent, but there is no response yet
@ -665,13 +669,13 @@ function $HttpProvider() {
}
} else {
// put the promise for the non-transformed response into cache as a placeholder
cache.put(config.url, promise);
cache.put(url, promise);
}
}
// if we won't have the response in cache, send the request to the backend
if (!cachedResp) {
$httpBackend(config.method, config.url, reqData, done, reqHeaders, config.timeout);
$httpBackend(config.method, url, reqData, done, reqHeaders, config.timeout);
}
return promise;
@ -686,10 +690,10 @@ function $HttpProvider() {
function done(status, response, headersString) {
if (cache) {
if (isSuccess(status)) {
cache.put(config.url, [status, response, parseHeaders(headersString)]);
cache.put(url, [status, response, parseHeaders(headersString)]);
} else {
// remove promise from the cache
cache.remove(config.url);
cache.remove(url);
}
}
@ -719,5 +723,21 @@ function $HttpProvider() {
if (idx !== -1) $http.pendingRequests.splice(idx, 1);
}
}
function buildUrl(url, params) {
if (!params) return url;
var parts = [];
forEachSorted(params, function(value, key) {
if (value == null || value == undefined) return;
if (isObject(value)) {
value = toJson(value);
}
parts.push(encodeURIComponent(key) + '=' + encodeURIComponent(value));
});
return url + ((url.indexOf('?') == -1) ? '?' : '&') + parts.join('&');
}
}];
}

View file

@ -132,6 +132,26 @@ describe('$http', function() {
// TODO(vojta): test passing timeout
describe('params', function() {
it('should do basic request with params and encode', inject(function($httpBackend, $http) {
$httpBackend.expect('GET', '/url?a%3D=%3F%26&b=2').respond('');
$http({url: '/url', params: {'a=':'?&', b:2}, method: 'GET'});
}));
it('should merge params if url contains some already', inject(function($httpBackend, $http) {
$httpBackend.expect('GET', '/url?c=3&a=1&b=2').respond('');
$http({url: '/url?c=3', params: {a:1, b:2}, method: 'GET'});
}));
it('should jsonify objects in params map', inject(function($httpBackend, $http) {
$httpBackend.expect('GET', '/url?a=1&b=%7B%22c%22%3A3%7D').respond('');
$http({url: '/url', params: {a:1, b:{c:3}}, method: 'GET'});
}));
});
describe('callbacks', function() {
it('should pass in the response object when a request is successful', function() {