2014-07-02 10 views
6

Mi aspettavo che AngularJS codificasse i parametri della stringa di query utilizzando la funzione javascript standard encodeURIComponent. Secondo la seguente prova non è il caso:Angularjs Come codificare i componenti uri

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

Il test ha esito negativo con il seguente errore:

$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

Riassumendo:

  • codifica prevista: Hello%20from%20http%3A%2F%2Fexample.com
  • Codifica effettiva: Hello+from+http:%2F%2Fexample.com

Quale metodo di codifica componente uri (ovvero parametri stringa di query) dovrei aspettarmi con AngularJS?

risposta

4

angolare (almeno 1.3) non solo utilizzare encodeURIComponent e cambia alcune sostituzioni (come "" a "+").

questo è il commit che spiega perché: https://github.com/angular/angular.js/commit/9e30baad3feafc82fb2f2011fd3f21909f4ba29e

Ed ecco quello che potete vedere in 1,3 fonti:

/** 
* 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' : '+')); 
} 

nota che pctEncodeSpaces è hardcoded a true;

Ecco cosa si può fare per decodificare URI parametri

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

Possiamo accedervi in ​​qualche modo come angular.encodeUriQuery o qualcosa del genere? –

-3

Sembra che quando si passa la pre-codifica dei parametri. Codifica l'URL ma dopo aver passato un url non codificato tramite il parametro dei dati JSON. Forse questa modifica al tuo codice funzionerà.

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

Inoltre, Dopo aver preso solo il pezzo codifica URL e collocandolo all'interno di un violino: http://jsfiddle.net/eNtgL/1/

E sembra funzionare correttamente, si potrebbe voler indagare i fattori esterni che causano il problema con il vostro URL. Ci sono anche diverse altre opzioni descritte qui in questa

Encode URL in JavaScript?

+1

Hi - Sto passando la codifica pre parametro, perché mi aspetto AngularJS (quadro js che sto usando qui) di farlo per me. E lo fa. Ma in un modo che non mi aspetto. Non esegue la codifica tramite la funzione 'encodeURIComponent'. La mia domanda è specifica per AngularJS. – nakhli

+0

Si prega di provare la pre-codifica per il mio codice sopra. Apporta la seguente modifica a questa linea. var data = encodeURIComponent ('Ciao da http://example.com'); –

+1

Non riesco a codificare i dati che passo al framework per la comunicazione con il server. Secondo la documentazione la funzione '$ http' dovrebbe farlo in modo trasparente. Ed effettivamente lo fa in modo corretto. Il mio problema riguarda principalmente il test, come nel test sui gelsomini che ho inserito nella mia domanda. La pre-codifica nel mio codice non è accettabile. – nakhli

4

A mio modesto parere AngularJS erroneamente codifica nello stesso modo in segmenti di percorso Uri e parametri di query URI. Per me questo è un bug e in realtà ho emesso un pull request per ripararlo.

Il test che ho introdotto nella richiesta pull conferma effettivamente questo errore (lo ha verificato con AngularJS 1.3.* e corrente master).

Problemi correlati