188

Вопрос по encoding – URL и плюсы

Я знаю, что+ в строке запроса URL-адрес представляет собой пробел. Это также имеет место за пределами области строки запроса? То есть, делает следующий URL:

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

на самом деле представляют:

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

(и, следовательно, должны быть закодированы, если это на самом деле должно быть+), или это на самом деле представляетa+b/c?

  • Видите, теперь у меня есть дополнительная путаница. В приведенном выше примере a.com% 2Fa% 2Bb - это не то, что я хочу, а по крайней мере a.com/a%2Bb. Это фактический URL, с которым я имею дело, а не URL, передаваемый в качестве параметра в строке запроса. Для небольшого фона, который может помочь прояснить, Mac OS X Finder возвращает мне URL файловой системы. Поэтому, если у меня есть файл с именем & quot; a? + B.txt & quot ;, он возвращает что-то, похожее на & quot; file: //a%3F+b.txt" ;, NOT & file: // a% 3F% 2B .txt & Quot ;. Является ли искатель просто неверным, или + перед строкой запроса на самом деле плюс?

    от Francisco Ryan Tolmasky I
  • Джонатан: Вы уверены, что 1738 говорит, что + зарезервировано? Я вижу: safe = & quot; $ & quot; | & Quot; - & Quot; | & Quot; _ & Quot; | & Quot;. & Quot; | & Quot; + & Quot; незарезервированный = альфа | цифра | безопасно | дополнительно, а также: Таким образом, только буквенно-цифровые символы, специальные символы "$ -_. +! *" (), "зарезервированные символы", используемые для их зарезервированных целей, могут использоваться в URL без кодирования.

    от
  • RFC 1738 однако рассматривает плюсы как пробелы. Все зависит от того, что реализовано вашими функциями кодирования / декодирования. например, в php rawurlencode следует rfc 1738, тогда как urlencode следует rfc 2396.

    от
  • Чтобы получить литерал +, который будет получен серверной частью (или, по крайней мере, PHP), он должен быть тройным кодированием:%25252B

    от
  • @Pacerier и @bukzor:RFC 1738 (с изменениями 2396 и 3986) определяет схему (http:), власть (//server.example.com) и путь (/myfile/mypage.htm) и не определяет какого-либо особого значения для+ персонаж. Спецификация HTML определяет компонент запроса как тип MIMEapplication/x-www-form-urlencoded который определяется как "заменить пробелы на+ и другие специальные символы, как в RFC1738 ". Таким образом, это не "от дикого", но это от принятого (не RFC) стандарта.

    от
  • Я не уверен, что это правильно. Согласно RFC2396 (ietf.org/rfc/rfc2396.txt) плюсы не являются зарезервированными символами в пути (сегментах) URI, а только компонентом запроса. Это, по-видимому, подразумевает, что они не должны кодироваться URL-адресом и, следовательно, не должны интерпретироваться как пробелы в пути, только в запросе.

    от
  • @Stobor Разве RFC когда-либо заявлял, что+ символ интерпретируется как пробел в компоненте запроса? Или это просто правило "из дикой природы"?

    от
  • @AndrewBarber Почему вы нашли это неуместным? + становится% 2B

    от
  • «Ты всегда будешь спасаться» нуждается в большей квалификации, и ответ в любом случае не имеет отношения к вопросу.

    от
  • Это совершенно законно для буквального +. символы для отображения вpath компонент на URL.

    от
  • +1 К сожалению, многие & quot; URL-кодировщики / кодировщики & quot; там в дикой природе это не понять. Напримерsislands.com/coin70/week6/encoder.htm keyone.co.uk/tools-url-encoder.asp meyerweb.com/eric/tools/dencoder

    от
  • Мне очень странно, что два человека проголосовали за этот ответ. Это буквально не имеет ничего общего с вопросом.

    от
  • Знак плюс в строке запроса может быть закодирован с использованием%2B.

    от
  • Этот ответ совершенно не имеет отношения к вопросу.

    от
  • @Stobor: цитирование необходимо.

    от
  • Как насчет других символов * @ - _ +. /

    от
  • Это неправильно по многим причинам ...escape устарела, вместо этого вы должны использоватьencodeURI или в случае части запросаencodeURIComponent, Также строка параметра должна кодироваться в соответствии сw3c.

    от
  • Это не решает вопрос. И неправильно кодирует URL-адреса на определенном языке (JavaScript) - в зависимости от контекста, вы, вероятно, не хотите кодировать, где вам нужны специальные (не буквальные) косые черты (/) и двоеточия (:) для работы URL-адреса ,

    от
  • Обратите внимание, что в php urldecode декодирует% 2b (кодированный +) в пробел. Чтобы избежать этого использованияrawurldecode, Я говорю это здесь для справки, потому что это высокий результат при поиске в Google по запросу "php url decode breaks on plus symbol".

    от danielson317
  • Спасибо, это действительно помогло мне!

    от
  • Возможный дубликатWhen to encode space to plus (+) or %20?

    от user
  • w3schools.com/tags/ref_urlencode.asp

    от Pratik Butani
6 ответов
  • -3

    Попробуйте ниже:

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

  • 158

    Чтобы быть явным:

    Percent encoding in the path section of a URL is expected to be decoded, but any + characters in the path component is expected to be treated literally.

    + это только специальный символ в компоненте запроса.

  • 203

    Вы можете найти хороший список соответствующих кодированных символов U

    RL наW3Schools.

    + becomes %2B space becomes %20

  • -5

    Ты всегда должен кодировать URL.

    Вот как Ruby кодирует ваш URL:

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

  • 1

    используйте функцию encodeURIComponent для исправления URL

    она работает в браузере и node.js

    res.redirect("/signin?email="+encodeURIComponent("[email protected]"));
    
    
    > encodeURIComponent("http://a.com/a+b/c")
    'http%3A%2F%2Fa.com%2Fa%2Bb%2Fc'
    

  • 17

    Пробел может быть закодирован только как "+" в одном контексте

    пары ключ-значение application / x-www-form-urlencoded.

    RFC-1866 (спецификация HTML 2.0), пункт 8.2.1. Подпункт 1. гласит: «Имена и значения полей формы экранируются: пробельные символы заменяются на« + », а затем зарезервированные символы экранируются»).

    Вот пример такой строки в URL, где RFC-1866 допускает кодирование пробелов в виде плюсов: & quot;http://example.com/over/there?name=foo+bar& Quot ;. Таким образом, только после «?» Пробелы могут быть заменены на плюсы (в других случаях пробелы должны быть закодированы в% 20). Этот способ кодирования данных формы также приведен в более поздних спецификациях HTML, например, ищите соответствующие параграфы о application / x-www-form-urlencoded в HTML 4.01 Specification и так далее.

    Но, поскольку трудно всегда правильно определить контекст, наилучшей практикой является никогда не кодировать пробелы как "+". Лучше кодировать в процентах все символы, кроме "безрезервированных". определено в RFC-3986, п.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;