空格字符只能在一种情况下编码为“+”: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 规范中也有给出,例如在 HTML 4.01 规范中查找关于application/x-www-form-urlencoded 的相关段落等等。
但是,由于很难始终正确确定上下文,因此最好不要将空格编码为“+”。最好对除 RFC-3986, p.2.3 中定义的“未保留”之外的所有字符进行百分比编码。这是一个代码示例,说明了应该编码的内容。它是用 Delphi (pascal) 编程语言提供的,但是无论拥有何种语言,它都非常容易理解它对任何程序员的工作原理:
(* 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;