Um espaço html é mostrado como% 2520 em vez de% 20

109

Passando um nome de arquivo para o navegador Firefox faz com que ele substitua os espaços com %2520 em vez de %20.

Eu tenho o seguinte HTML em um arquivo chamado myhtml.html:

<img src="C:\Documents and Settings\screenshots\Image01.png"/>

Quando eu carrego myhtml.htmlno firefox, a imagem aparece como uma imagem quebrada. Então, clico com o botão direito no link para ver a imagem e ela mostra este URL modificado:

file:///c:/Documents%2520and%2520Settings/screenshots/Image01.png
                    ^
                    ^-----Firefox changed my space to %2520.

Que diabos? Ele converteu meu espaço em um %2520. Não deveria estar convertendo em um %20?

Como altero este arquivo HTML para que o navegador possa localizar minha imagem? O que está acontecendo aqui?

Eric Leschinski
fonte

Respostas:

219

Um pouco de explicação sobre o que %2520é:

O caractere de espaço comum é codificado %20conforme você mesmo observou. O %personagem é codificado como %25.

A forma como você obtém %2520é quando seu url já tem um %20nele e é codificado novamente, o que transforma o %20em %2520.

Você (ou qualquer estrutura que esteja usando) possui caracteres de codificação dupla?

Edit: Expandindo um pouco sobre isso, especialmente para links LOCAL . Supondo que você deseja vincular ao recurso C:\my path\my file.html:

  • se você fornecer apenas um caminho de arquivo local, espera-se que o navegador codifique e proteja todos os caracteres fornecidos (no exemplo acima, você deve fornecer espaços como mostrado, já que %é um caractere de nome de arquivo válido e, como tal, será codificado) ao converter para um URL adequado (veja o próximo ponto).
  • se você fornecer uma URL com o file://protocolo, estará basicamente declarando que tomou todas as precauções e codificou o que precisa ser codificado, o resto deve ser tratado como caracteres especiais. No exemplo acima, você deve fornecer file:///c:/my%20path/my%20file.html. Além de corrigir barras, os clientes não devem codificar caracteres aqui.

NOTAS:

  • Direção da barra - barras normais /são usadas em URLs, barras reversas \em caminhos do Windows, mas a maioria dos clientes trabalhará com ambas convertendo-as na barra adequada.
  • Além disso, existem 3 barras após o nome do protocolo, uma vez que você está se referindo silenciosamente à máquina atual em vez de um host remoto (o caminho não abreviado completo seria file://localhost/c:/my%20path/my%file.html), mas, novamente, a maioria dos clientes funcionarão sem a parte do host (ou seja, apenas duas barras ) assumindo que você quer dizer a máquina local e adicionando a terceira barra.
Nick Andriopoulos
fonte
1
Hexblot está realmente correto aqui. Normalmente, isso acontece quando você está codificando novamente seus urls por meio de programação e um bot chega e o codifica uma segunda vez. Os bots têm o péssimo hábito de fazer isso. Existem duas maneiras de lidar com esse problema. 1) Você pode 404 ou 401 com uma exceção try catch ou pode escrever uma pequena função que decodificará os valores decodificados duplos antes de transferi-los para outro método de lógica de negócios.
Ryan Watts,
Isso me ajudou a descobrir por que eu estava recebendo ao enviar uma solicitação jQuery ajax. Eu estava definindo o atributo de dados em uma solicitação GET ajax com a função encodeURIComponent no valor, mas o jQuery já faz isso por padrão, por isso estou recebendo% 2520. Obrigado muito útil.
Asher
Não existe um argumento de linha de comando para o cromo dizer a ele interpretar ou não interpretar o link?
AleX_
Eu tenho http://mysite/test & that... If I use UrlEncode` que muda para, http://mysite/test%20&%20thatmas também quero &mudar para% 26, então é meu site / teste% 20% 26% 20que `Como posso fazer isso?
Si8
10

Por algum motivo - possivelmente válido - o url foi codificado duas vezes. %25é o %sinal codificado pelo URL . Portanto, o url original se parecia com:

http://server.com/my path/

Em seguida, foi codificado em url uma vez:

http://server.com/my%20path/

e duas vezes:

http://server.com/my%2520path/

Portanto, você não deve fazer nenhum urlencoding - no seu caso - como outros componentes já parecem fazer isso para você. Use apenas um espaço

hek2mgl
fonte
Eu tenho o mesmo problema, mas não entendo por que o urlencoding padrão foi processado duas vezes na primeira vez.
jungwon jin de
Dependendo da situação, a codificação dupla pode ser um resultado perfeitamente válido do uso correto da codificação. Essa resposta pode criar a impressão de que a codificação dupla está sempre errada e que você pode simplesmente corrigir os problemas de codificação adicionando quantas chamadas de codificação / descodificação forem necessárias para "fazer funcionar". Isso está errado, e é assim que os bugs de codificação surgem em primeiro lugar. -1
Florian Winter
@FlorianWinter Eu realmente não vejo onde você lê isso nas entrelinhas. Você pode me ajudar? (Leia a pergunta e minha resposta)
hek2mgl
7

Quando você está tentando visitar um nome de arquivo local através do navegador firefox, você tem que forçar o file:\\\protocolo ( http://en.wikipedia.org/wiki/File_URI_scheme ) ou então o firefox codificará seu espaço DUAS VEZES. Altere o snippet html deste:

<img src="C:\Documents and Settings\screenshots\Image01.png"/>

para isso:

<img src="file:\\\C:\Documents and Settings\screenshots\Image01.png"/>

ou isto:

<img src="file://C:\Documents and Settings\screenshots\Image01.png"/>

Em seguida, o firefox é notificado de que este é um nome de arquivo local e processa a imagem corretamente no navegador, codificando corretamente a string uma vez.

Link útil: http://support.mozilla.org/en-US/questions/900466

Eric Leschinski
fonte
0

O seguinte trecho de código resolveu meu problema. Achei que isso pudesse ser útil para outras pessoas.

var strEnc = this.$.txtSearch.value.replace(/\s/g, "-");
strEnc = strEnc.replace(/-/g, " ");

Em vez de usar o padrão, encodeURIComponentminha primeira linha de código é converter tudo spacesem um hyphenspadrão regex /\s\ge a linha seguinte apenas faz o inverso, ou seja, converte tudo de hyphensvolta em spacesoutro regex pattern /-/g. Aqui /gé realmente responsável por finding allcombinar personagens.

Quando estou enviando esse valor para minha chamada Ajax, ele percorre como normal spacesou simplesmente %20e, portanto, é eliminado double-encoding.

Subrata Sarkar
fonte
1
Suponho que porque você não está resolvendo o problema, apenas encobrindo - a causa raiz ainda está em algum lugar, e você está fazendo um trabalho duplo (em algum lugar você está acidentalmente codificando duas vezes, e em outro lugar você está decodificando manualmente para cobrir isso). Supondo que você queira fazer as coisas "corretamente", a melhor coisa seria depurar e encontrar o verdadeiro culpado.
Nick Andriopoulos
Na verdade, a solução funcionou para mim sempre que encontrei esse problema. Então eu postei.
Subrata Sarkar
2
@NiladriSarkar, o que hexbolt estava tentando dizer é que, embora seu código funcione, não é uma solução viável, e sim uma correção suja, e deve ser evitada ...
2Dee
-1

Experimente isso?

encodeURIComponent('space word').replace(/%20/g,'+')

Esperançoso
fonte
1
Bem-vindo ao StackOverflow! Geralmente as respostas são mais úteis se incluírem alguma explicação sobre por que sua sugestão resolverá o problema do OP, em vez de apenas um trecho de código. Além disso, como esta pergunta já tem uma resposta aceita, seria uma boa ideia adicionar alguma explicação de por que sua resposta é mais correta do que essa.
DaveyDaveDave