Um `+` em um esquema de URL / host / caminho representa um espaço?


224

Estou ciente de que um +na cadeia de consulta de um URL representa um espaço. Este também é o caso fora da região da string de consulta? Ou seja, faz o seguinte URL:

http://a.com/a+b/c

realmente representam:

http://a.com/a b/c

(e, portanto, precisa ser codificado se realmente for a +), ou será que realmente representa a+b/c?



4
Note que no php urldecode decodifica o% 2b (codificado +) para um espaço. Para evitar esse uso rawurldecode. Digo isso aqui para referência, porque este é um resultado bem classificado na pesquisa do google por "php url decode breaks on plus symbol".
Danielson317 31/03

Respostas:


170
  • A porcentagem de codificação na seção de caminho de um URL deve ser decodificada, mas
  • +espera-se que qualquer caractere no componente de caminho seja tratado literalmente.

Para ser explícito: +é apenas um caractere especial no componente de consulta.


12
+1 Infelizmente, muitos "codificadores / codificadores de URL" disponíveis no mercado não entendem isso. Por exemplo, sislands.com/coin70/week6/encoder.htm keyone.co.uk/tools-url-encoder.asp meyerweb.com/eric/tools/dencoder
leonbloy

11
@ Stobor: citação necessária.
bukzor

8
@Stobor O RFC já declarou que o +caractere é interpretado como um espaço no componente de consulta? Ou é simplesmente uma regra "do nada"?
Pacerier

44
@Pacerier e @bukzor: a RFC 1738 (modificada por 2396 e 3986) define o esquema ( http:), a autoridade ( //server.example.com) e o caminho ( /myfile/mypage.htm), e não define nenhum significado especial para o +personagem. A especificação HTML define o componente de consulta como tipo mime application / x-www-form-urlencoded, que é definido como "substituir espaços por +e outros caracteres especiais como no RFC1738". Portanto, não é "do nada", mas é de um padrão aceito (não RFC).
Stobor

2
O método .NET Server.UrlEncodecodifica erroneamente os espaços como pontos positivos na parte do caminho, violando as regras HTTP.
Suncat2000

243

Você pode encontrar uma boa lista de caracteres codificados em URL correspondentes no W3Schools .

  • + torna-se %2B
  • o espaço se torna %20

18
É perfeitamente legal que caracteres '+' literais apareçam no componente do caminho em uma URL.
Sam Stainsby

4
Para que um + literal seja recebido pelo back-end (ou pelo menos PHP), ele deve ser codificado três vezes:%25252B
Umbrella

11
Esta resposta é completamente irrelevante para a pergunta.
Nisse Engström

22

Os caracteres de espaço podem ser codificados apenas como "+" em um contexto: pares de valores-chave application / x-www-form-urlencoded.

A RFC-1866 (especificação HTML 2.0), parágrafo 8.2.1. o parágrafo 1. diz: "Os nomes e valores dos campos do formulário são escapados: caracteres de espaço são substituídos por` + 'e caracteres reservados são escapados ").

Aqui está um exemplo de uma string no URL em que o RFC-1866 permite espaços de codificação como vantagens: " http://example.com/over/there?name=foo+bar ". Portanto, somente após "?", Os espaços podem ser substituídos por vantagens (em outros casos, os espaços devem ser codificados para% 20). Essa maneira de codificar dados de formulário também é fornecida em especificações HTML posteriores, por exemplo, procure parágrafos relevantes sobre application / x-www-form-urlencoded na especificação HTML 4.01 e assim por diante.

Mas, como é difícil sempre determinar corretamente o contexto, é a melhor prática nunca codificar espaços como "+". É melhor codificar em porcentagem todos os caracteres, exceto "não reservado", definido na RFC-3986, p.2.3. Aqui está um exemplo de código que ilustra o que deve ser codificado. É fornecida na linguagem de programação Delphi (pascal), mas é muito fácil entender como funciona para qualquer programador, independentemente da linguagem possuída:

(* percent-encode all unreserved characters as defined in RFC-3986, p.2.3 *)
function UrlEncodeRfcA(const S: AnsiString): AnsiString;
const    
  HexCharArrA: array [0..15] of AnsiChar = '0123456789ABCDEF';
var
  I: Integer;
  c: AnsiChar;
begin
 // percent-encoding, see RFC-3986, p. 2.1
  Result := S;
  for I := Length(S) downto 1 do
  begin
    c := S[I];
    case c of
      'A' .. 'Z', 'a' .. 'z', // alpha
      '0' .. '9',             // digit
      '-', '.', '_', '~':;    // rest of unreserved characters as defined in the RFC-3986, p.2.3
      else
        begin
          Result[I] := '%';
          Insert('00', Result, I + 1);
          Result[I + 1] := HexCharArrA[(Byte(C) shr 4) and $F)];
          Result[I + 2] := HexCharArrA[Byte(C) and $F];
        end;
    end;
  end;
end;

function UrlEncodeRfcW(const S: UnicodeString): AnsiString;
begin
  Result := UrlEncodeRfcA(Utf8Encode(S));
end;

0

use a função encodeURIComponent para corrigir o URL, ele funciona no navegador e no node.js

res.redirect("/signin?email="+encodeURIComponent("aaa+bbb-ccc@example.com"));


> encodeURIComponent("http://a.com/a+b/c")
'http%3A%2F%2Fa.com%2Fa%2Bb%2Fc'

1
Isso não aborda a questão. E, codifica incorretamente URLs, com um idioma específico (JavaScript) - dependendo do contexto, você provavelmente não deseja codificar onde precisa de barras especiais (não literais) (/) e dois pontos (:) para que o URL funcione .
Gremio

Graças realmente me ajudou!
Qwsd

-2

Tente abaixo:

<script type="text/javascript">

function resetPassword() {
   url: "submitForgotPassword.html?email="+fixEscape(Stringwith+char);
}
function fixEscape(str)
{
    return escape(str).replace( "+", "%2B" );
}
</script>

2
Acho muito estranho que duas pessoas votem nessa resposta. Literalmente, nada tem a ver com a pergunta.
Andrew Barber

1
Que tal para outros caracteres * @ - _ +. /
Ravi

1
@AndrewBarber Por que você achou irrelevante? + torna-se% 2B
O cara Java

Isso está errado por muitos motivos ... escapeestá obsoleto. Em vez disso, você deve usar encodeURIou no caso da parte da consulta encodeURIComponent. Além disso, a cadeia de parâmetros deve codificar de acordo com w3c .
Christoph

-5

Você sempre deve codificar URLs.

Aqui está como o Ruby codifica seu URL:

irb(main):008:0> CGI.escape "a.com/a+b"
=> "a.com%2Fa%2Bb"

8
Não tenho certeza se está certo. De acordo com o RFC2396 ( ietf.org/rfc/rfc2396.txt ), os pontos positivos não são caracteres reservados no caminho (segmentos) do URI, apenas o componente de consulta. Isso parece implicar que eles não precisam ser codificados por URL e, portanto, não devem ser interpretados como espaços no caminho, apenas na consulta.
tlrobinson

3
A RFFC 1738, no entanto, trata vantagens como espaços. Tudo depende do que é implementado pelas suas funções de codificação / decodificação. por exemplo, em php, rawurlencode segue RFC 1738 enquanto urlencode segue RFC 2396.
Jonathan Fingland

1
Veja, agora eu tenho alguma confusão adicional. No exemplo que você me deu acima, a.com% 2Fa% 2Bb não é o que eu quero, seria no mínimo a.com/a%2Bb. Este é um URL real com o qual estou lidando, e não um URL que está sendo passado como parâmetro em uma string de consulta. Para um pouco de esclarecimento que pode ajudar a esclarecer, o Mac OS X Finder está retornando os URLs do sistema de arquivos para mim. Portanto, se eu tiver um arquivo chamado "a? + B.txt", ele retornará algo parecido com "file: //a%3F+b.txt", NOT "file: //a%3F%2B.txt" . O localizador está incorreto ou é um + antes da string de consulta realmente um plus?
Francisco Ryan Tolmasky I

2
Jonathan: Você tem certeza que 1738 diz que + está reservado? Entendo: safe = "$" | "-" "_" "." | "+" não reservado = alfa | dígito | seguro | extra e também: portanto, apenas alfanuméricos, os caracteres especiais "$ -_. +! * '()" e os caracteres reservados usados ​​para fins reservados podem ser usados ​​sem codificação em um URL.
tlrobinson

2
"Sempre escaparás" precisa de mais qualificação, e a resposta é irrelevante para a pergunta de qualquer maneira.
bug
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.