Devo usar encodeURI ou encodeURIComponent para codificar URLs?

282

Qual desses dois métodos deve ser usado para codificar URLs?

Aditya Shukla
fonte
3
Consulte também stackoverflow.com/a/3608791/632951
Pacerier (
13
Uma grande diferença é que encodeURInão codificará /: encodeURIComponent("ac/dc")=> ac%2Fdce encodeURI("ac/dc")=> #ac/dc
Isso pode ser útil: "encodeURIComponent() and encodeURI() encode a URI by replacing URL reserved characters with their UTF-8 encoding....They differ because encodeURI does not encode queryString or hash values...URLs do not allow many special characters, like spaces or slashes. However these special characters are part of life, so URL encoding was invented." Origem
user1063287
Ver também a secção específica intitulado encodeURIComponent differs from encodeURI as followsem: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
user1063287

Respostas:

324

Depende do que você realmente deseja fazer.

encodeURI assume que a entrada é um URI completo que pode ter alguns caracteres que precisam ser codificados.

encodeURIComponent codificará tudo com significado especial; portanto, você o usará para componentes de URIs como

var world = "A string with symbols & characters that have special meaning?";
var uri = 'http://example.com/foo?hello=' + encodeURIComponent(world);
Quentin
fonte
108

Se você estiver codificando uma string para inserir um componente de URL (um parâmetro de string de consulta), deve ligar encodeURIComponent.

Se você estiver codificando um URL existente, ligue encodeURI.

SLaks
fonte
1
Se eu estiver usando o ajax, como decodificar o URL que é passado para o php?
Aditya Shukla
6
Você não O servidor da web faz isso automaticamente.
Quentin
@ Aditya: Depende do que você está fazendo.
SLaks
Estou passando parâmetros via get, então eu quero recuperá-los em php.
Aditya Shukla
2
Bem. Eu poderia ter falado um pouco apressadamente quando disse que o servidor da web faria isso, mas qualquer biblioteca que você usa para ler os dados do formulário cuidará disso para você.
Quentin
47

O xkr.us tem uma ótima discussão, com exemplos. Para citar seu resumo:

O método escape () não codifica o caractere + que é interpretado como um espaço no lado do servidor e gerado por formulários com espaços em seus campos. Devido a essa falha e ao fato de que essa função falha ao manipular caracteres não ASCII corretamente, você deve evitar o uso de escape () sempre que possível. A melhor alternativa é geralmente encodeURIComponent ().

escape () não codifica: @ * / +

O uso do método encodeURI () é um pouco mais especializado do que escape (), na medida em que codifica para URIs em oposição à querystring, que faz parte de uma URL. Use esse método quando precisar codificar uma sequência a ser usada para qualquer recurso que use URIs e precise que certos caracteres permaneçam não codificados. Observe que esse método não codifica o caractere ', pois é um caractere válido nos URIs.

encodeURI () não codifica: ~! @ # $ & * () =: /,;? + '

Por fim, o método encodeURIComponent () deve ser usado na maioria dos casos ao codificar um único componente de um URI. Esse método codifica certos caracteres que normalmente seriam reconhecidos como caracteres especiais para URIs, para que muitos componentes possam ser incluídos. Observe que esse método não codifica o caractere ', pois é um caractere válido nos URIs.

encodeURIComponent () não codifica: ~! * () '

BrianFreud
fonte
Recentemente aprendi. Os servidores TOMCAT 9 são mais específicos sobre o que você pode enviar para o URL. encodeURIComponent () parece funcionar melhor nos casos em que você tem "espaços" no que precisa codificar. O Tomcat 8 não se importava, mas o 9 é muito mais específico.
Aggie Jon de
Em outras palavras, encodeURIfalhará se você estiver tentando converter um nome de arquivo em um URL e o nome do arquivo #estiver nele
gman
17

Aqui está um resumo.

  1. escape () não codifica @ * _ + -. /

    Não use isso.

  2. encodeURI () não codificará AZ az 0-9; , /? : @ & = + $ - _. ! ~ * '() #

    Use-o quando sua entrada for um URL completo como ' https://searchexample.com/search?q=wiki '

  3. encodeURIComponent () não codifica AZ az 0-9 - _. ! ~ * '() Use-o quando sua entrada fizer parte de um URL completo, por exemplo const queryStr = encodeURIComponent(someString)
Frank Wang
fonte
1
Esta é uma excelente resposta, porque diz exatamente o que eles fazem. No entanto, ainda tenho uma pergunta sobre qual devo usar e quando. E se o meu componente URI for um URL completo? Devo então usar regra 2 ou 3 Regra de cima ou talvez ambos como encodeURIComponent (encodeURI (theCompleteURI))
Panu Logic
10

encodeURIComponent (): assume que seu argumento é uma parte (como o protocolo, nome do host, caminho ou cadeia de caracteres da consulta) de um URI. Portanto, ele escapa os caracteres de pontuação usados ​​para separar as partes de um URI.

encodeURI (): é usado para codificar o URL existente

Gopal
fonte
7

Diferença entre encodeURIe encodeURIComponent:

encodeURIComponent(value)é usado principalmente para codificar valores de parâmetro queryString e codifica todos os caracteres aplicáveis ​​em value. encodeURIignora o prefixo do protocolo ( http://) e o nome do domínio.


Em casos muito, muito raros, quando você deseja implementar a codificação manual para codificar caracteres adicionais (embora eles não precisem ser codificados em casos típicos) como:, ! *então você pode usar:

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

( fonte )

T.Todua
fonte
6
Você não deve escapar desses caracteres no URL.
Arashsoft
Como a documentação citada diz: "esses personagens não têm formalizado URI delimitando usos"
caesarsol
@caesarsol então, devo editar minha resposta. deixe-me saber seus pensamentos, porque eu não consigo entender o que isso citados meios de documentação ..
T.Todua
é apenas inútil para codificar esses caracteres, a menos que você está fazendo algo fora dos casos de uso de codificação de URL normais :)
caesarsol
2

Outras respostas descrevem os propósitos. Aqui estão os caracteres que cada função realmente converterá :

control = '\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F'
        + '\x10\x11\x12\x13\x14\X15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F'
                                                                    + '\x7F'
encodeURI         (control + ' "%<>[\\]^`{|}'                             )
encodeURIComponent(control + ' "%<>[\\]^`{|}' + '#$&,:;=?' + '+/@'        )
escape            (control + ' "%<>[\\]^`{|}' + '#$&,:;=?' +       "!'()~")

Todos os caracteres acima são convertidos em códigos percentuais hexadecimais. Espaço para %20, porcentagem para %25etc. Os caracteres abaixo passam inalterados.

Aqui estão os caracteres que as funções NÃO converterão :

pass_thru = '*-._0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'

encodeURI         (pass_thru + '#$&,:;=?' + '+/@' + "!'()~")
encodeURIComponent(pass_thru +                      "!'()~")
escape            (pass_thru +              '+/@'          )
Bob Stein
fonte
-4

Como regra geral, use encodeURIComponent. Não tenha medo do nome longo, pensando que é mais específico em seu uso, para mim é o método mais comumente usado. Além disso, não se preocupe em usar o encodeURI porque você o testou e parece estar codificando corretamente, provavelmente não é o que você queria usar e, embora seu teste simples usando "Fred" em um campo de nome tenha funcionado, você encontrará mais tarde, quando você usar texto mais avançado, como adicionar um e comercial ou hashtag, ele falhará. Você pode olhar para as outras respostas pelos motivos pelos quais isso acontece.

Helzgate
fonte