@@ -9,6 +9,64 @@ var JSON_ENDS = {
9
9
} ;
10
10
var JSON_PROTECTION_PREFIX = / ^ \) \] \} ' , ? \n / ;
11
11
12
+ function paramSerializerFactory ( jQueryMode ) {
13
+
14
+ function serializeValue ( v ) {
15
+ if ( isObject ( v ) ) {
16
+ return isDate ( v ) ? v . toISOString ( ) : toJson ( v ) ;
17
+ }
18
+ return v ;
19
+ }
20
+
21
+ return function paramSerializer ( params ) {
22
+ if ( ! params ) return '' ;
23
+ var parts = [ ] ;
24
+ forEachSorted ( params , function ( value , key ) {
25
+ if ( value === null || isUndefined ( value ) ) return ;
26
+ if ( isArray ( value ) || isObject ( value ) && jQueryMode ) {
27
+ forEach ( value , function ( v , k ) {
28
+ var keySuffix = jQueryMode ? '[' + ( ! isArray ( value ) ? k : '' ) + ']' : '' ;
29
+ parts . push ( encodeUriQuery ( key + keySuffix ) + '=' + encodeUriQuery ( serializeValue ( v ) ) ) ;
30
+ } ) ;
31
+ } else {
32
+ parts . push ( encodeUriQuery ( key ) + '=' + encodeUriQuery ( serializeValue ( value ) ) ) ;
33
+ }
34
+ } ) ;
35
+
36
+ return parts . length > 0 ? parts . join ( '&' ) : '' ;
37
+ } ;
38
+ }
39
+
40
+ function $HttpParamSerializerProvider ( ) {
41
+ /**
42
+ * @ngdoc service
43
+ * @name $httpParamSerializer
44
+ * @description
45
+ *
46
+ * Default $http params serializer that converts objects to a part of a request URL
47
+ * according to the following rules:
48
+ * * `{'foo': 'bar'}` results in `foo=bar`
49
+ * * `{'foo': Date.now()}` results in `foo=2015-04-01T09%3A50%3A49.262Z` (`toISOString()` and encoded representation of a Date object)
50
+ * * `{'foo': ['bar', 'baz']}` results in `foo=bar&foo=baz` (repeated key for each array element)
51
+ * * `{'foo': {'bar':'baz'}}` results in `foo=%7B%22bar%22%3A%22baz%22%7D"` (stringified and encoded representation of an object)
52
+ * */
53
+ this . $get = function ( ) {
54
+ return paramSerializerFactory ( false ) ;
55
+ } ;
56
+ }
57
+
58
+ function $HttpParamSerializerJQLikeProvider ( ) {
59
+ /**
60
+ * @ngdoc service
61
+ * @name $httpParamSerializerJQLike
62
+ *
63
+ * Alternative $http params serializer that follows jQuerys `param()` method {http://api.jquery.com/jquery.param/} logic.
64
+ * */
65
+ this . $get = function ( ) {
66
+ return paramSerializerFactory ( true ) ;
67
+ } ;
68
+ }
69
+
12
70
function defaultHttpResponseTransform ( data , headers ) {
13
71
if ( isString ( data ) ) {
14
72
// Strip json vulnerability protection prefix and trim whitespace
@@ -153,6 +211,11 @@ function $HttpProvider() {
153
211
* - **`defaults.headers.put`**
154
212
* - **`defaults.headers.patch`**
155
213
*
214
+ * - **`defaults.paramSerializer`** - {string|function(Object<string,string>):string} - A function used to prepare string representation
215
+ * of request parameters (specified as an object).
216
+ * Is specified as string, it is interpreted as function registered in with the {$injector}.
217
+ * Defaults to {$httpParamSerializer}.
218
+ *
156
219
**/
157
220
var defaults = this . defaults = {
158
221
// transform incoming response data
@@ -174,7 +237,9 @@ function $HttpProvider() {
174
237
} ,
175
238
176
239
xsrfCookieName : 'XSRF-TOKEN' ,
177
- xsrfHeaderName : 'X-XSRF-TOKEN'
240
+ xsrfHeaderName : 'X-XSRF-TOKEN' ,
241
+
242
+ paramSerializer : '$httpParamSerializer'
178
243
} ;
179
244
180
245
var useApplyAsync = false ;
@@ -188,7 +253,7 @@ function $HttpProvider() {
188
253
* significant performance improvement for bigger applications that make many HTTP requests
189
254
* concurrently (common during application bootstrap).
190
255
*
191
- * Defaults to false. If no value is specifed , returns the current configured value.
256
+ * Defaults to false. If no value is specified , returns the current configured value.
192
257
*
193
258
* @param {boolean= } value If true, when requests are loaded, they will schedule a deferred
194
259
* "apply" on the next tick, giving time for subsequent requests in a roughly ~10ms window
@@ -225,6 +290,12 @@ function $HttpProvider() {
225
290
226
291
var defaultCache = $cacheFactory ( '$http' ) ;
227
292
293
+ /**
294
+ * Make sure that default param serializer is exposed as a function
295
+ */
296
+ defaults . paramSerializer = isString ( defaults . paramSerializer ) ?
297
+ $injector . get ( defaults . paramSerializer ) : defaults . paramSerializer ;
298
+
228
299
/**
229
300
* Interceptors stored in reverse order. Inner interceptors before outer interceptors.
230
301
* The reversal is needed so that we can build up the interception chain around the
@@ -636,6 +707,9 @@ function $HttpProvider() {
636
707
* response body, headers and status and returns its transformed (typically deserialized) version.
637
708
* See {@link ng.$http#overriding-the-default-transformations-per-request
638
709
* Overriding the Default Transformations}
710
+ * - **paramSerializer** - {string|function(Object<string,string>):string} - A function used to prepare string representation
711
+ * of request parameters (specified as an object).
712
+ * Is specified as string, it is interpreted as function registered in with the {$injector}.
639
713
* - **cache** – `{boolean|Cache}` – If true, a default $http cache will be used to cache the
640
714
* GET request, otherwise if a cache instance built with
641
715
* {@link ng.$cacheFactory $cacheFactory}, this cache will be used for
@@ -764,11 +838,14 @@ function $HttpProvider() {
764
838
var config = extend ( {
765
839
method : 'get' ,
766
840
transformRequest : defaults . transformRequest ,
767
- transformResponse : defaults . transformResponse
841
+ transformResponse : defaults . transformResponse ,
842
+ paramSerializer : defaults . paramSerializer
768
843
} , requestConfig ) ;
769
844
770
845
config . headers = mergeHeaders ( requestConfig ) ;
771
846
config . method = uppercase ( config . method ) ;
847
+ config . paramSerializer = isString ( config . paramSerializer ) ?
848
+ $injector . get ( config . paramSerializer ) : config . paramSerializer ;
772
849
773
850
var serverRequest = function ( config ) {
774
851
var headers = config . headers ;
@@ -1032,7 +1109,7 @@ function $HttpProvider() {
1032
1109
cache ,
1033
1110
cachedResp ,
1034
1111
reqHeaders = config . headers ,
1035
- url = buildUrl ( config . url , config . params ) ;
1112
+ url = buildUrl ( config . url , config . paramSerializer ( config . params ) ) ;
1036
1113
1037
1114
$http . pendingRequests . push ( config ) ;
1038
1115
promise . then ( removePendingReq , removePendingReq ) ;
@@ -1139,27 +1216,9 @@ function $HttpProvider() {
1139
1216
}
1140
1217
1141
1218
1142
- function buildUrl ( url , params ) {
1143
- if ( ! params ) return url ;
1144
- var parts = [ ] ;
1145
- forEachSorted ( params , function ( value , key ) {
1146
- if ( value === null || isUndefined ( value ) ) return ;
1147
- if ( ! isArray ( value ) ) value = [ value ] ;
1148
-
1149
- forEach ( value , function ( v ) {
1150
- if ( isObject ( v ) ) {
1151
- if ( isDate ( v ) ) {
1152
- v = v . toISOString ( ) ;
1153
- } else {
1154
- v = toJson ( v ) ;
1155
- }
1156
- }
1157
- parts . push ( encodeUriQuery ( key ) + '=' +
1158
- encodeUriQuery ( v ) ) ;
1159
- } ) ;
1160
- } ) ;
1161
- if ( parts . length > 0 ) {
1162
- url += ( ( url . indexOf ( '?' ) == - 1 ) ? '?' : '&' ) + parts . join ( '&' ) ;
1219
+ function buildUrl ( url , serializedParams ) {
1220
+ if ( serializedParams . length > 0 ) {
1221
+ url += ( ( url . indexOf ( '?' ) == - 1 ) ? '?' : '&' ) + serializedParams ;
1163
1222
}
1164
1223
return url ;
1165
1224
}
0 commit comments