Skip to content Skip to sidebar Skip to footer

Angularjs How Uri Components Are Encoded

I was expecting AngularJS to encode query string parameters using the standard javascript function encodeURIComponent. According to the following test it is not the case: describe(

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

Encode URL in JavaScript?

Post a Comment for "Angularjs How Uri Components Are Encoded"