On my current project I have a drupal backend that exposes rest services for my frontend. Some calls to my backend don't really like url entities to get encoded.
So my question is: how do I disable URL encoding of some parameters?
Example:
I need to call my backend with a "+"-sign between different search terms. Like so:
http://backend.com/someservice/search/?terms=search+terms+here
But angular, setup like so:
var resource = $resource(
backendUrl + '/views/:view', {},
{
'search': {params:{view:'searchposts'}, isArray:true}
}
);
// search posts for the given terms
this.searchPosts = function(terms, limit) {
resource.search({search:terms.join('+'), limit:limit});
};
Calls the following url:
http://backend.com/someservice/search/?terms=search%2Bterms%2Bhere
Any suggestions? Thanks!
Update: with the new httpParamSerializer in Angular 1.4 you can do it by writing your own paramSerializer and setting $httpProvider.defaults.paramSerializer
.
Below only applies to AngularJS 1.3 (and older).
It is not possible without changing the source of AngularJS.
This is done by $http:
https://github.com/angular/angular.js/tree/v1.3.0-rc.5/src/ng/http.js#L1057
function buildUrl(url, params) {
if (!params) return url;
var parts = [];
forEachSorted(params, function(value, key) {
if (value === null || isUndefined(value)) return;
if (!isArray(value)) value = [value];
forEach(value, function(v) {
if (isObject(v)) {
v = toJson(v);
}
parts.push(encodeUriQuery(key) + '=' +
encodeUriQuery(v));
});
});
if(parts.length > 0) {
url += ((url.indexOf('?') == -1) ? '?' : '&') + parts.join('&');
}
return url;
}
encodeUriQuery
uses the standard encodeUriComponent
(MDN) which replaces the '+' with '%2B'
Too bad you cannot overwrite encodeUriQuery
because it is a local variable inside the angular function.
So the only option I see is to overwrite window.encodeURIComponent
. I've done it in an $http interceptor to minimize the impact. Note that the original function is only put back when the response comes back, so this change is global (!!) while your request is ongoing. So be sure to test if this doesn't break something else in your application.
app.config(function($httpProvider) {
$httpProvider.interceptors.push(function($q) {
var realEncodeURIComponent = window.encodeURIComponent;
return {
'request': function(config) {
window.encodeURIComponent = function(input) {
return realEncodeURIComponent(input).split("%2B").join("+");
};
return config || $q.when(config);
},
'response': function(config) {
window.encodeURIComponent = realEncodeURIComponent;
return config || $q.when(config);
}
};
});
});
AngularJS only runs the encodeUriQuery method if you pass your params as an extra object. If you manually create your own param string and concatenate it onto your URL then Angular won't modify it.
It's pretty simple to convert the param object yourself, here's an example: How to serialize an Object into a list of parameters?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With