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;