it-swarm-pt.tech

Quando você deve usar o escape em vez de encodeURI/encodeURIComponent?

Ao codificar uma string de consulta a ser enviada para um servidor web - quando você usa escape() e quando você usa encodeURI() ou encodeURIComponent():

Use escape:

escape("% +&=");

OR

use encodeURI ()/encodeURIComponent ()

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

encodeURIComponent("var1=value1&var2=value2");
1323
Adam

escapar()

Não use! escape() é definido na seção B.2.1.2 escape e o texto de introdução do Anexo B diz:

... Todos os recursos e comportamentos de linguagem especificados neste anexo têm uma ou mais características indesejáveis ​​e, na ausência de uso de legado, seriam removidos desta especificação. ...
... Os programadores não devem usar ou assumir a existência desses recursos e comportamentos ao escrever o novo código ECMAScript ....

Comportamento:

https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/escape

Caracteres especiais são codificados com a exceção de: @ * _ + -. /

A forma hexadecimal para caracteres, cujo valor da unidade de código é 0xFF ou menor, é uma seqüência de escape de dois dígitos: %xx.

Para caracteres com uma unidade de código maior, o formato de quatro dígitos %uxxxx é usado. Isso não é permitido em uma string de consulta (conforme definido em RFC3986 ):

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

Um sinal de porcentagem só é permitido se for seguido diretamente por dois hexdigits, percentual seguido por u não é permitido.

encodeURI ()

Use encodeURI quando quiser um URL funcional. Faça esta ligação:

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

para obter:

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

Não chame encodeURIComponent, pois isso destruiria o URL e retornaria

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

encodeURIComponent ()

Use encodeURIComponent quando quiser codificar o valor de um parâmetro de URL.

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

Então você pode criar o URL que você precisa:

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

E você receberá este URL completo:

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

Observe que o encodeURIComponent não escapa do caractere '. Um erro comum é usá-lo para criar atributos html, como href='MyUrl', que podem sofrer um erro de injeção. Se você estiver construindo html a partir de strings, use " em vez de ' para aspas de atributo, ou adicione uma camada extra de codificação (' pode ser codificado como% 27).

Para obter mais informações sobre esse tipo de codificação, você pode verificar: http://en.wikipedia.org/wiki/Percent-encoding

1847
Arne Evertsson

A diferença entre encodeURI() e encodeURIComponent() tem exatamente 11 caracteres codificados por encodeURIComponent, mas não por encodeURI:

Table with the ten differences between encodeURI and encodeURIComponent

Gerei esta tabela facilmente com console.table no Google Chrome com este código:

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

411
Johann Echavarria

Eu achei este artigo esclarecedor: Javascript Madness: Query String Parsing

Eu encontrei quando estava tentando entender porque o decodeURIComponent não estava decodificando '+' corretamente. Aqui está um extrato:

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!
43
Damien

encodeURIComponent não codifica -_.!~*'(), causando problema ao postar dados em php em xml string.

Por exemplo:
<xml><text x="100" y="150" value="It's a value with single quote" /> </xml>

Escape geral com 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

Você pode ver, aspas simples não estão codificadas. Para resolver o problema, criei duas funções para resolver o problema no meu projeto, para a URL de codificação:

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

Para o URL de decodificação:

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 "";
}
38
Kirankumar Sripati

encodeURI () - a função escape () é para escape de javascript, não HTTP.

37
Daniel Papasian

Pequena tabela de comparação 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
16
30thh

Eu recomendo não usar um desses métodos como é. Escreva sua própria função, que faz a coisa certa.

O MDN deu um bom exemplo na codificação de URL mostrada abaixo.

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/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent

11
Jerry Joseph

Lembre-se também de que todos eles codificam diferentes conjuntos de caracteres e selecionam o que você precisa apropriadamente. encodeURI () codifica menos caracteres que encodeURIComponent (), que codifica menos (e também diferentes, para ponto de dannyp) caracteres que escape ().

10
Pseudo Masochist

Para o propósito de codificar javascript deu três funções embutidas -

  1. escape () - não codifica @*/+ Este método é obsoleto após o ECMA 3, portanto deve ser evitado.

  2. encodeURI () - não codifica [email protected]#$&*()=:/,;?+' Ele assume que o URI é um URI completo, portanto, não codifica caracteres reservados que tenham significado especial no URI. Esse método é usado quando a intenção é para converter o URL completo em vez de algum segmento especial de URL. Exemplo - encodeURI('http://stackoverflow.com'); dará - http://stackoverflow.com

  3. encodeURIComponent () - não codifica - _ . ! ~ * ' ( ) Essa função codifica um componente URI (Uniform Resource Identifier) ​​substituindo cada instância de determinados caracteres por uma, duas, três ou quatro seqüências de escape representando a codificação UTF-8 do personagem. Esse método deve ser usado para converter um componente de URL. Por exemplo, alguma entrada do usuário precisa ser anexada Exemplo - encodeURI('http://stackoverflow.com'); Dará - http% 3A% 2F% 2Fstackoverflow.com

Toda essa codificação é executada em UTF 8, ou seja, os caracteres serão convertidos no formato UTF-8. 

encodeURIComponent difere de encodeURI por codificar caracteres reservados e número de sinal # de encodeURI

6
Gaurav Tiwari

Descobri que experimentar com os vários métodos é uma boa verificação de sanidade, mesmo depois de ter uma boa noção de quais são seus vários usos e capacidades.

Para esse fim eu encontrei este site extremamente útil para confirmar minhas suspeitas de que estou fazendo algo de forma adequada. Ele também provou ser útil para decodificar uma seqüência de caracteres encodeURIComponented que pode ser um pouco difícil de interpretar. Um ótimo marcador para ter:

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

3
veeTrain

Eu tenho essa função ...

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;
};
1
molokoloco

A resposta aceita é boa. Para estender a última parte:

Note que encodeURIComponent não escapa do caractere. Um erro comum É usá-lo para criar atributos html, como href = 'MyUrl', que Poderia sofrer um erro de injeção. Se você estiver construindo html a partir de Strings, use "em vez de" para citações de atributos ou adicione uma camada extra de codificação ('Pode ser codificada como% 27).

Se você quer estar no lado seguro, porcentagem de codificação de caracteres não reservados também deve ser codificada. 

Você pode usar este método para escapar deles (source Mozilla )

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

// fixedEncodeURIComponent("'") --> "%27"
1
Michael

Reescrita moderna da resposta de @ 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
        )
)

Ou se você puder usar uma tabela, substitua console.log por console.table (para a saída mais bonita).

1
ryanpcmcquen

Inspirado pela tabela de Johann , decidi estender a tabela. Eu queria ver quais caracteres ASCII são codificados.

screenshot of console.table

var ascii = " !\"#$%&'()*+,-./0123456789:;<=>[email protected][\\]^_`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);

Tabela mostra apenas os caracteres codificados. Células vazias significam que o original e os caracteres codificados são os mesmos.


Apenas para ser extra, estou adicionando outra tabela para urlencode() vs rawurlencode() . A única diferença parece ser a codificação do caractere espacial.

screenshot of console.table

<script>
<?php
$ascii = str_split(" !\"#$%&'()*+,-./0123456789:;<=>[email protected][\\]^_`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>
0
akinuri