Quando dovresti usare l’escape invece di encodeURI / encodeURIComponent?

Quando si codifica una stringa di query da inviare a un server Web, quando si utilizza escape() e quando si utilizza encodeURI() o encodeURIComponent() :

Usa la fuga:

 escape("% +&="); 

O

usa encodeURI () / encodeURIComponent ()

 encodeURI("http://www.google.com?var1=value1&var2=value2"); encodeURIComponent("var1=value1&var2=value2"); 

fuga()

Non usarlo! escape() è definito nella sezione B.2.1.2 escape e il testo introduttivo dell’allegato B dice:

… Tutte le caratteristiche e i comportamenti linguistici specificati in questo allegato hanno una o più caratteristiche indesiderabili e in assenza di un uso legacy sarebbero rimossi da questa specifica. …
… I programmatori non dovrebbero usare o assumere l’esistenza di queste caratteristiche e comportamenti quando scrivono un nuovo codice ECMAScript ….

Comportamento:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/escape

I caratteri speciali sono codificati con l’eccezione di: @ * _ + -. /

La forma esadecimale per i caratteri, il cui valore unitario del codice è 0xFF o inferiore, è una sequenza di escape a due cifre: %xx .

Per i caratteri con un’unità di codice maggiore, viene utilizzato il formato a quattro cifre %uxxxx . Questo non è consentito all’interno di una stringa di query (come definito in RFC3986 ):

 query = *( pchar / "/" / "?" ) pchar = unreserved / pct-encoded / sub-delims / ":" / "@" unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" pct-encoded = "%" HEXDIG HEXDIG sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "=" 

Un segno di percentuale è consentito solo se è seguito direttamente da due caratteri esadecimali, la percentuale seguita da u non è consentita.

encodeURI ()

Usa encodeURI quando vuoi un URL funzionante. Effettua questa chiamata:

 encodeURI("http://www.example.org/a file with spaces.html") 

ottenere:

 http://www.example.org/a%20file%20with%20spaces.html 

Non chiamare encodeURIComponent poiché distruggerebbe l’URL e restituirebbe

 http%3A%2F%2Fwww.example.org%2Fa%20file%20with%20spaces.html 

encodeURIComponent ()

Utilizzare encodeURIComponent quando si desidera codificare il valore di un parametro URL.

 var p1 = encodeURIComponent("http://example.org/?a=12&b=55") 

Quindi puoi creare l’URL che ti serve:

 var url = "http://example.net/?param1=" + p1 + "&param2=99"; 

E otterrai questo URL completo:

http://example.net/?param1=http%3A%2F%2Fexample.org%2F%Ffa%3D12%26b%3D55&param2=99

Nota che encodeURIComponent non sfugge al carattere. Un bug comune è usarlo per creare attributi html come href='MyUrl' , che potrebbe subire un bug di iniezione. Se stai costruendo html dalle stringhe, usa " invece di ' per le virgolette degli attributi, oppure aggiungi un ulteriore livello di codifica ( ' può essere codificato come% 27).

Per maggiori informazioni su questo tipo di codifica puoi controllare: http://en.wikipedia.org/wiki/Percent-encoding

La differenza tra encodeURI() e encodeURIComponent() sono esattamente 11 caratteri codificati da encodeURIComponent ma non da encodeURI:

Tabella con le dieci differenze tra encodeURI e encodeURIComponent

Ho generato questa tabella facilmente con console.table in Google Chrome con questo codice:

 var arr = []; for(var i=0;i<256;i++) { var char=String.fromCharCode(i); if(encodeURI(char)!==encodeURIComponent(char)) { arr.push({ character:char, encodeURI:encodeURI(char), encodeURIComponent:encodeURIComponent(char) }); } } console.table(arr); 

Ho trovato questo articolo illuminante: Javascript Madness: analisi delle stringhe di query

L’ho trovato quando stavo cercando di capire perché decodeURIComponent non stava decodificando ‘+’ correttamente. Ecco un estratto:

 String: "A + B" Expected Query String Encoding: "A+%2B+B" escape("A + B") = "A%20+%20B" Wrong! encodeURI("A + B") = "A%20+%20B" Wrong! encodeURIComponent("A + B") = "A%20%2B%20B" Acceptable, but strange Encoded String: "A+%2B+B" Expected Decoding: "A + B" unescape("A+%2B+B") = "A+++B" Wrong! decodeURI("A+%2B+B") = "A+++B" Wrong! decodeURIComponent("A+%2B+B") = "A+++B" Wrong! 

encodeURIComponent non codifica -_.!~*'() , causando problemi nella pubblicazione dei dati su php nella stringa xml.

Per esempio:

Fuga generale con encodeURI
%3Cxml%3E%3Ctext%20x=%22100%22%20y=%22150%22%20value=%22It's%20a%20value%20with%20single%20quote%22%20/%3E%20%3C/xml%3E

Puoi vedere, la citazione singola non è codificata. Per risolvere il problema, ho creato due funzioni per risolvere il problema nel mio progetto, per l’URL di codifica:

 function encodeData(s:String):String{ return encodeURIComponent(s).replace(/\-/g, "%2D").replace(/\_/g, "%5F").replace(/\./g, "%2E").replace(/\!/g, "%21").replace(/\~/g, "%7E").replace(/\*/g, "%2A").replace(/\'/g, "%27").replace(/\(/g, "%28").replace(/\)/g, "%29"); } 

Per l’URL di decodifica:

 function decodeData(s:String):String{ try{ return decodeURIComponent(s.replace(/\%2D/g, "-").replace(/\%5F/g, "_").replace(/\%2E/g, ".").replace(/\%21/g, "!").replace(/\%7E/g, "~").replace(/\%2A/g, "*").replace(/\%27/g, "'").replace(/\%28/g, "(").replace(/\%29/g, ")")); }catch (e:Error) { } return ""; } 

encodeURI () – la funzione escape () è per l’escavazione javascript, non HTTP.

Piccola tabella di comparazione Java vs JavaScript vs. PHP.

 1. Java URLEncoder.encode (using UTF8 charset) 2. JavaScript encodeURIComponent 3. JavaScript escape 4. PHP urlencode 5. PHP rawurlencode char JAVA JavaScript --PHP--- [ ] + %20 %20 + %20 [!] %21 ! %21 %21 %21 [*] * * * %2A %2A ['] %27 ' %27 %27 %27 [(] %28 ( %28 %28 %28 [)] %29 ) %29 %29 %29 [;] %3B %3B %3B %3B %3B [:] %3A %3A %3A %3A %3A [@] %40 %40 @ %40 %40 [&] %26 %26 %26 %26 %26 [=] %3D %3D %3D %3D %3D [+] %2B %2B + %2B %2B [$] %24 %24 %24 %24 %24 [,] %2C %2C %2C %2C %2C [/] %2F %2F / %2F %2F [?] %3F %3F %3F %3F %3F [#] %23 %23 %23 %23 %23 [[] %5B %5B %5B %5B %5B []] %5D %5D %5D %5D %5D ---------------------------------------- [~] %7E ~ %7E %7E ~ [-] - - - - - [_] _ _ _ _ _ [%] %25 %25 %25 %25 %25 [\] %5C %5C %5C %5C %5C ---------------------------------------- char -JAVA- --JavaScript-- -----PHP------ [ä] %C3%A4 %C3%A4 %E4 %C3%A4 %C3%A4 [ф] %D1%84 %D1%84 %u0444 %D1%84 %D1%84 

Ricorda anche che tutti codificano diversi set di caratteri e selezionano quello che ti serve in modo appropriato. encodeURI () codifica un numero inferiore di caratteri rispetto a encodeURIComponent (), che codifica meno (e anche diversi, rispetto ai punti di dannyp) di escape ().

Raccomando di non usare uno di quei metodi così com’è. Scrivi la tua funzione che fa la cosa giusta.

MDN ha dato un buon esempio sulla codifica url mostrata di seguito.

 var fileName = 'my file(2).txt'; var header = "Content-Disposition: attachment; filename*=UTF-8''" + encodeRFC5987ValueChars(fileName); console.log(header); // logs "Content-Disposition: attachment; filename*=UTF-8''my%20file%282%29.txt" function encodeRFC5987ValueChars (str) { return encodeURIComponent(str). // Note that although RFC3986 reserves "!", RFC5987 does not, // so we do not need to escape it replace(/['()]/g, escape). // ie, %27 %28 %29 replace(/\*/g, '%2A'). // The following are not required for percent-encoding per RFC5987, // so we can allow for a little better readability over the wire: |`^ replace(/%(?:7C|60|5E)/g, unescape); } 

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent

Ai fini della codifica javascript ha dato tre funzioni integrate –

  1. escape () – non codifica @*/+ Questo metodo è deprecato dopo ECMA 3 quindi dovrebbe essere evitato.

  2. encodeURI () – non codifica ~!@#$&*()=:/,;?+' Suppone che l’URI sia un URI completo, quindi non codifica i caratteri riservati che hanno un significato speciale nell’URI. Questo metodo viene utilizzato quando l’intento è di convertire l’URL completo invece di un segmento speciale di URL. Esempio: encodeURI('http://stackoverflow.com'); darà – http://stackoverflow.com

  3. encodeURIComponent () – does not encode - _ . ! ~ * ' ( ) - _ . ! ~ * ' ( ) - _ . ! ~ * ' ( ) Questa funzione codifica un componente URI (Uniform Resource Identifier) ​​sostituendo ciascuna istanza di determinati caratteri con una, due, tre o quattro sequenze di escape che rappresentano la codifica UTF-8 del carattere. Questo metodo dovrebbe essere usato per convertire un componente di URL. Ad esempio, è necessario aggiungere un input utente Esempio – encodeURI('http://stackoverflow.com'); darà – http% 3A% 2F% 2Fstackoverflow.com

Tutta questa codifica viene eseguita in UTF 8, ovvero i caratteri verranno convertiti in formato UTF-8.

encodeURIComponent differisce da encodeURI in quanto codifica caratteri riservati e numero di segno # di encodeURI

Ho scoperto che sperimentare con i vari metodi è un buon test di integrità anche dopo aver avuto una buona idea di quali siano i loro vari usi e funzionalità.

A tal fine, ho trovato questo sito estremamente utile per confermare i miei sospetti che sto facendo qualcosa in modo appropriato. Si è anche dimostrato utile per decodificare una stringa encodeURIComponent che può essere piuttosto difficile da interpretare. Un grande segnalibro da avere:

http://www.the-art-of-web.com/javascript/escape/

Ho questa funzione …

 var escapeURIparam = function(url) { if (encodeURIComponent) url = encodeURIComponent(url); else if (encodeURI) url = encodeURI(url); else url = escape(url); url = url.replace(/\+/g, '%2B'); // Force the replacement of "+" return url; }; 

La risposta accettata è buona. Per estendere l’ultima parte:

Nota che encodeURIComponent non sfugge al carattere. Un bug comune è usarlo per creare attributi html come href = ‘MyUrl’, che potrebbe subire un bug di iniezione. Se stai costruendo html dalle stringhe, usa “invece di” per le virgolette degli attributi, oppure aggiungi un ulteriore livello di codifica (‘può essere codificato come% 27).

Se si vuole essere sicuri, anche la codifica per cento dei caratteri non riservati dovrebbe essere codificata.

Puoi usare questo metodo per sfuggire a loro (fonte Mozilla )

 function fixedEncodeURIComponent(str) { return encodeURIComponent(str).replace(/[!'()*]/g, function(c) { return '%' + c.charCodeAt(0).toString(16); }); } // fixedEncodeURIComponent("'") --> "%27" 

Riscrittura moderna della risposta di @ johann-echavarria:

 console.log( Array(256) .fill() .map((ignore, i) => String.fromCharCode(i)) .filter( (char) => encodeURI(char) !== encodeURIComponent(char) ? { character: char, encodeURI: encodeURI(char), encodeURIComponent: encodeURIComponent(char) } : false ) )