Domanda

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

Usa fuga:

escape("% +&=");

O

usa encodeURI() / encodeURIComponent()

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

encodeURIComponent("var1=value1&var2=value2");
È stato utile?

Soluzione

fuga()

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

...Tutte le caratteristiche linguistiche e i comportamenti specificati in questo allegato hanno una o più caratteristiche indesiderabili e in assenza di un utilizzo ereditato verrebbero rimossi da questa specifica....
...I programmatori non dovrebbero utilizzare o presumere l'esistenza di queste funzionalità e comportamenti durante la scrittura di nuovo codice ECMAScript....

Comportamento:

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

I caratteri speciali sono codificati ad eccezione di:@*_+-./

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

Per i caratteri con un'unità di codice maggiore, il formato a quattro cifre %uxxxx si usa.Ciò 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 cifre esadecimali, seguito da percentuale u non è permesso.

codificaURI()

Utilizza encodeURI quando desideri un URL funzionante.Fai 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

codificaURIComponente()

Utilizza encodeURIComponent quando desideri 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

Tieni presente che encodeURIComponent non esegue l'escape del file ' carattere.Un bug comune è usarlo per creare attributi html come href='MyUrl', che potrebbe soffrire di un bug di iniezione.Se stai costruendo HTML da stringhe, usa " invece di ' per le virgolette degli attributi o 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

Altri suggerimenti

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

Table with the ten differences between encodeURI and encodeURIComponent

Ho generato facilmente questa tabella con console.tabella 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:Follia Javascript:Analisi della stringa di query

L'ho trovato mentre cercavo di capire perché decodeURIComponent non decodificava 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:
<xml><text x="100" y="150" value="It's a value with single quote" /> </xml>

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 che la virgoletta singola non è codificata.Per risolvere il problema ho creato due funzioni per risolvere il problema nel mio progetto, per la codifica dell'URL:

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 la decodifica dell'URL:

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'escape javascript, non per HTTP.

Piccola tabella comparativa 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

Raccomando di non utilizzare uno di questi metodi così com'è.Scrivi la tua funzione che fa la cosa giusta.

MDN ha fornito un buon esempio sulla codifica dell'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). // i.e., %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

Ricorda inoltre che codificano tutti diversi set di caratteri e seleziona quello che ti serve in modo appropriato.encodeURI() codifica meno caratteri di encodeURIComponent(), che codifica meno caratteri (e anche diversi, secondo Dannyp) di escape().

Allo scopo di codificare Javascript ha fornito tre funzioni integrate:

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

  2. encodeURI() - non codifica ~!@#$&*()=:/,;?+'Si presuppone 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 è convertire l'URL completo anziché un segmento speciale di URL.Esempio - encodeURI('http://stackoverflow.com');darà - http://stackoverflow.com

  3. encodeURIComponent() -non codifica - _ . ! ~ * ' ( )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 utilizzato per convertire un componente dell'URL.Ad esempio, alcuni input dell'utente devono essere aggiunti ad 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 i caratteri riservati e il segno numerico # di encodeURI

Ho scoperto che sperimentare i vari metodi è un buon controllo di integrità anche dopo aver capito bene quali sono i loro vari usi e capacità.

A tal fine ho trovato questo sito web estremamente utile per confermare i miei sospetti che sto facendo qualcosa di appropriato.Si è dimostrato utile anche per decodificare una stringa codificata URIComponent che può essere piuttosto difficile da interpretare.Un ottimo segnalibro da avere:

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

Ispirato da Il tavolo di Johann, ho deciso di allungare il tavolo.Volevo vedere quali caratteri ASCII vengono codificati.

screenshot of console.table

var ascii = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";

var encoded = [];

ascii.split("").forEach(function (char) {
    var obj = { char };
    if (char != encodeURI(char))
        obj.encodeURI = encodeURI(char);
    if (char != encodeURIComponent(char))
        obj.encodeURIComponent = encodeURIComponent(char);
    if (obj.encodeURI || obj.encodeURIComponent)
        encoded.push(obj);
});

console.table(encoded);

La tabella mostra solo i caratteri codificati.Le celle vuote indicano che i caratteri originali e codificati sono gli stessi.


Giusto per essere extra, sto aggiungendo un altro tavolo per urlencode() contro rawurlencode().L'unica differenza sembra essere la codifica del carattere spazio.

screenshot of console.table

<script>
<?php
$ascii = str_split(" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~", 1);
$encoded = [];
foreach ($ascii as $char) {
    $obj = ["char" => $char];
    if ($char != urlencode($char))
        $obj["urlencode"] = urlencode($char);
    if ($char != rawurlencode($char))
        $obj["rawurlencode"] = rawurlencode($char);
    if (isset($obj["rawurlencode"]) || isset($obj["rawurlencode"]))
        $encoded[] = $obj;
}
echo "var encoded = " . json_encode($encoded) . ";";
?>
console.table(encoded);
</script>

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:

Tieni presente che encodeURIComponent non esegue l'escape del carattere '.Un bug comune è usarlo per creare attributi HTML come Href = 'Myurl', che potrebbe subire un bug di iniezione.Se stai costruendo HTML da stringhe, usa "invece di" per le citazioni di attributi o aggiungi un ulteriore livello di codifica ("può essere codificato come %27).

Se vuoi andare sul sicuro, percentuale di codifica dei caratteri non riservati dovrebbe essere codificato anch'esso.

Puoi usare questo metodo per sfuggirli (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
        )
)

Oppure, se puoi usare una tabella, sostituiscila console.log con console.table (per l'output più carino).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top