URL и плюсы
Я знаю, что +
в строке запроса URL-адрес представляет собой пробел. Это также имеет место за пределами области строки запроса? То есть, делает следующий URL:
http://a.com/a+b/c
на самом деле представляют:
http://a.com/a b/c
(и, следовательно, должны быть закодированы, если это на самом деле должно быть +
), или это на самом деле представляет a+b/c
?
6 ответов
- Ожидается, что процентное кодирование в разделе пути URL будет декодировано, но
- любой
+
ожидается, что символы в компоненте path будут трактоваться буквально.
Чтобы быть явным: +
это только специальный символ в компоненте запроса.
Вы можете найти хороший список соответствующих символов в кодировке URL на W3Schools.
+
становится%2B
- пространство становится
%20
Символы пробела могут быть закодированы как "+" только в одном контексте: пары ключ-значение 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;
Используйте функцию encodeURIComponent для исправления URL, она работает в браузере и 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'
Попробуйте ниже:
<script type="text/javascript">
function resetPassword() {
url: "submitForgotPassword.html?email="+fixEscape(Stringwith+char);
}
function fixEscape(str)
{
return escape(str).replace( "+", "%2B" );
}
</script>
Ты всегда будешь кодировать URL.
Вот как Ruby кодирует ваш URL:
irb(main):008:0> CGI.escape "a.com/a+b"
=> "a.com%2Fa%2Bb"