Пробел может быть закодирован как «+» только в одном контексте: пары ключ-значение application / x-www-form-urlencoded.
RFC-1866 (спецификация HTML 2.0), пункт 8.2.1. в подпункте 1. говорится: «Имена и значения полей формы экранируются: пробельные символы заменяются на« + », а затем зарезервированные символы экранируются»).
Вот пример такой строки в URL, где RFC-1866 позволяет кодировать пробелы в виде плюсов: « http://example.com/over/there?name=foo+bar ». Таким образом, только после «?» Пробелы можно заменить на плюсы (в других случаях пробелы следует кодировать в% 20). Этот способ кодирования данных формы также приведен в более поздних спецификациях HTML, например, ищите соответствующие параграфы о application / x-www-form-urlencoded в HTML 4.01 Specification и так далее.
Но так как всегда трудно правильно определить контекст, лучше никогда не кодировать пробелы как «+». Лучше кодировать все символы в процентах, кроме «незарезервированных», определенных в RFC-3986, p.2.3. Вот пример кода, который иллюстрирует то, что должно быть закодировано. Он дан на языке программирования Delphi (паскаль), но очень легко понять, как он работает для любого программиста, независимо от того, какой язык он обладает:
(* 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;