2014-07-02 5 views
6

Ich erwartete AngularJS Abfrage String-Parameter mit der Standard-JavaScript-Funktion encodeURIComponent zu kodieren. Nach dem folgenden Test ist es nicht der Fall:Angularjs Wie uri Komponenten codiert sind

describe('$http', function() { 
it('encodes uri components correctly', inject(function($http, $httpBackend) { 
    var data = 'Hello from http://example.com'; 
    $httpBackend.expectGET('/api/process?data=' + encodeURIComponent(data)); 
    $http({ method: 'GET', url: '/api/process', params: { data: data } }); 
    $httpBackend.flush(); 
})); 
}); 

Der Test mit dem folgenden Fehler fehl:

$http encodes uri components correctly
Error: Unexpected request: GET /api/process?data=Hello+from+http:%2F%2Fexample.com
Expected GET /api/process?data=Hello%20from%20http%3A%2F%2Fexample.com

Fazit:

  • Erwartete Codierung: Hello%20from%20http%3A%2F%2Fexample.com
  • Tatsächliche Kodierung: Hello+from+http:%2F%2Fexample.com

Welche Codierungsmethode für die Uri-Komponente (auch Abfrage-String-Parameter) sollte ich mit AngularJS erwarten?

Antwort

4

Angular (mindestens 1,3) nicht nur encodeURIComponent verwenden und ändern einigen Ersatz (wie „“ auf „+“).

dies ist die commit zu erklären, warum: https://github.com/angular/angular.js/commit/9e30baad3feafc82fb2f2011fd3f21909f4ba29e

Und hier, was Sie in 1.3 Quellen sehen:

/** 
* 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 = "!"/"$"/"&"/"'"/"("/")" 
*     /"*"/"+"/","/";"/"=" 
*/ 
function encodeUriQuery(val, pctEncodeSpaces) { 
    return encodeURIComponent(val). 
      replace(/%40/gi, '@'). 
      replace(/%3A/gi, ':'). 
      replace(/%24/g, '$'). 
      replace(/%2C/gi, ','). 
      replace(/%3B/gi, ';'). 
      replace(/%20/g, (pctEncodeSpaces ? '%20' : '+')); 
} 

beachten Sie, dass pctEncodeSpaces zu true fest einprogrammiert ist; URI Pfadsegmente und URI-Abfrageparameter

Hier ist, was Sie tun können,

decodeURIComponent(val. 
      replace('@', '%40'). 
      replace(':', '%3A'). 
      replace('$', '%24'). 
      replace(',', '%2C'). 
      replace(';', '%3B'). 
      replace('+', '%20')); 
+0

Können wir irgendwie auf angle.encodeUriQuery zugreifen oder so? –

-3

Es scheint, dass wenn Sie die Parameter Vorcodierung übergeben. Sie codieren die URL, aber nachdem Sie eine nicht codierte URL über den JSON-Datenparameter übergeben haben. Vielleicht funktioniert diese Änderung an Ihrem Code.

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(); 
})); 
}); 

Auch Nachdem nur die URL-Kodierung Stück zu nehmen und es in einer Geige platzieren: http://jsfiddle.net/eNtgL/1/

Es scheint, richtig zu arbeiten, können Sie auch externe Faktoren untersuchen, wollen das Problem mit Ihrem URL verursacht. Es gibt auch mehrere andere Möglichkeiten beschrieben hier in diesem

Encode URL in JavaScript?

+1

Hallo - Ich bin das Bestehen der Parameter Pre-Codierung, weil ich AngularJS erwarte (die js Rahmen, den ich hier bin mit) es für mich zu tun. Und es tut es. Aber ich erwarte es nicht. Die Codierung erfolgt nicht über die Funktion 'encodeURIComponent'. Meine Frage ist spezifisch für AngularJS. – nakhli

+0

Bitte versuchen Sie die Vorcodierung nach meinem obigen Code. Nehmen Sie folgende Änderung an dieser Zeile vor. var data = encodeURIComponent ('Hallo von http://example.com'); –

+1

Ich kann die Daten, die ich an das Framework für die Serverkommunikation übergebe, nicht selbst codieren. Laut der Dokumentation sollte die Funktion "$ http" dies transparent machen. Und es tut es tatsächlich richtig. Mein Problem besteht hauptsächlich im Testen, wie im Jasmin-Test, den ich in meine Frage mit einbezog. Vorcodierung in meinem Code ist nicht akzeptabel. – nakhli

4

In meiner bescheidenen Meinung nach AngularJS URI-Parameter ist falsch in der gleichen Art und Weise codiert, zu dekodieren. Für mich ist das ein Fehler und ich habe eine pull request für die Reparatur herausgegeben.

Der Test, den ich in der Pull-Anfrage einführe, bestätigt diesen Fehler (getestet mit AngularJS 1.3.* und aktuell master).

Verwandte Themen