Angularjs How Uri Components Are Encoded
Solution 1:
Angular (at least 1.3) doesn't only use encodeURIComponent and changes some replacements (like " " to "+").
this is the commit explaining why : https://github.com/angular/angular.js/commit/9e30baad3feafc82fb2f2011fd3f21909f4ba29e
And here's what you can see in 1.3 sources :
/**
* This method is intended for encoding *key* or *value* parts of query component. We need a custom
* method because encodeURIComponent is too aggressive and encodes stuff that doesn't have to be
* encoded per http://tools.ietf.org/html/rfc3986:
* query = *( pchar / "/" / "?" )
* pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
* unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
* pct-encoded = "%" HEXDIG HEXDIG
* sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
* / "*" / "+" / "," / ";" / "="
*/functionencodeUriQuery(val, pctEncodeSpaces) {
returnencodeURIComponent(val).
replace(/%40/gi, '@').
replace(/%3A/gi, ':').
replace(/%24/g, '$').
replace(/%2C/gi, ',').
replace(/%3B/gi, ';').
replace(/%20/g, (pctEncodeSpaces ? '%20' : '+'));
}
note that pctEncodeSpaces
is hardcoded to true
;
Here's what you can do to decode URI parameters
decodeURIComponent(val.
replace('@', '%40').
replace(':', '%3A').
replace('$', '%24').
replace(',', '%2C').
replace(';', '%3B').
replace('+', '%20'));
Solution 2:
In my humble opinion AngularJS is wrongly encoding in the same way URI path segments AND URI query parameters. To me this is a bug and I actually issued a pull request for fixing it.
The test I introduce in the pull request actually confirms this bug (tested it with both AngularJS 1.3.*
and current master
).
Solution 3:
It appears that when you are passing the parameters pre encoding. You encode the URL but after you pass a non-encoded url through the JSON data parameter. Maybe this alteration to your code will work.
describe('$http', function () {
it('encodes uri components correctly', inject(function($http, $httpBackend) {
var data = encodeURIComponent('Hello from http://example.com');
$httpBackend.expectGET('/api/process?data=' + encodeURIComponent(data));
$http({ method: 'GET', url: '/api/process', params: { data: data } });
$httpBackend.flush();
}));
});
Also, After taking only the URL encoding piece and placing it inside a fiddle: http://jsfiddle.net/eNtgL/1/
It appears to be working correctly, you may want to investigate external factors causing the issue with your URL. There are also several other options described here in this
Post a Comment for "Angularjs How Uri Components Are Encoded"