Пространство html отображается как% 2520 вместо% 20

110

Передача имени файла браузеру Firefox приводит к замене пробелов на %2520 вместо %20.

У меня есть следующий HTML-код в файле с именем myhtml.html:

<img src="C:\Documents and Settings\screenshots\Image01.png"/>

Когда я загружаюсь myhtml.htmlв firefox, изображение отображается как неработающее. Итак, я щелкаю правой кнопкой мыши ссылку, чтобы просмотреть изображение, и оно показывает этот измененный URL:

file:///c:/Documents%2520and%2520Settings/screenshots/Image01.png
                    ^
                    ^-----Firefox changed my space to %2520.

Какого черта? Он превратил мое пространство в файл %2520. Разве это не должно преобразовывать его в %20?

Как мне изменить этот HTML-файл, чтобы браузер мог найти мое изображение? Что тут происходит?

Эрик Лещинский
источник

Ответы:

219

Немного поясняю, что это %2520такое:

Символ общего пробела кодируется так, %20как вы сами заметили. Символ %кодируется как %25.

Вы получаете %2520это, когда в вашем URL-адресе уже есть %20и снова кодируется URL-адрес , который преобразует %20в %2520.

Вы (или любая другая структура, которую вы можете использовать) символы двойного кодирования?

Изменить: немного расширить это, особенно для ЛОКАЛЬНЫХ ссылок. Предполагая, что вы хотите разместить ссылку на ресурс C:\my path\my file.html:

  • если вы указываете только локальный путь к файлу, ожидается, что браузер закодирует и защитит все указанные символы (в приведенном выше примере вы должны указать его с пробелами, как показано, поскольку %это допустимый символ имени файла и, как таковой, он будет закодирован) при преобразовании на правильный URL (см. следующий пункт).
  • если вы предоставляете URL-адрес с file://протоколом, вы в основном заявляете, что вы приняли все меры предосторожности и закодировали то, что требует кодирования, остальное следует рассматривать как специальные символы. Таким образом, в приведенном выше примере вы должны предоставить file:///c:/my%20path/my%20file.html. Помимо исправления косой черты, клиенты не должны здесь кодировать символы.

НОТЫ:

  • Направление косой черты - прямые косые черты /используются в URL-адресах, обратные косые черты - \в путях Windows, но большинство клиентов будут работать с обоими, преобразовывая их в правильную косую черту.
  • Кроме того, после имени протокола есть 3 слэша, так как вы молча ссылаетесь на текущий компьютер вместо удаленного хоста (полный несокращенный путь будет file://localhost/c:/my%20path/my%file.html), но опять же, большинство клиентов будут работать без части хоста (т.е. только две слэши ), предполагая, что вы имеете в виду локальную машину, и добавив третью косую черту.
Ник Андриопулос
источник
1
Hexblot здесь действительно прав. Обычно это происходит, когда вы повторно кодируете URL-адреса с помощью программирования, а бот входит и кодирует его второй раз. У ботов есть дурная привычка делать это. Есть два способа справиться с этой проблемой. 1) Вы можете либо 404, либо 401 с исключением try catch, или вы можете написать небольшую функцию, которая будет декодировать двойные декодированные значения, прежде чем вы передадите ее другому методу бизнес-логики.
Райан Уоттс,
Это помогло мне понять, почему я получаю это при отправке запроса jQuery ajax. Я устанавливал атрибут данных в запросе ajax GET с функцией encodeURIComponent для значения, но jQuery уже делает это по умолчанию, поэтому я получал% 2520. Действительно полезно, спасибо.
Ашер
Разве для chrome нет аргумента командной строки, чтобы он либо интерпретировал, либо не интерпретировал ссылку?
AleX_
У меня есть http://mysite/test & that... If I use UrlEncode`, http://mysite/test%20&%20thatно я также хочу &изменить его на% 26, так что это mysite / test% 20% 26% 20that `Как я могу это сделать?
Si8
10

По какой-то - возможно, действительной - причине URL-адрес был закодирован дважды. %25это %знак urlencoded . Итак, исходный URL-адрес выглядел так:

http://server.com/my path/

Затем он был закодирован один раз:

http://server.com/my%20path/

и дважды:

http://server.com/my%2520path/

Таким образом, вам не следует делать urlencoding - в вашем случае - поскольку другие компоненты, похоже, уже это делают для вас. Используйте просто пробел

hek2mgl
источник
У меня такая же проблема, но я не понимаю, почему кодирование urlencoding по умолчанию было обработано дважды в первый раз.
jungwon jin
В зависимости от ситуации двойное кодирование может быть вполне допустимым результатом правильного использования кодирования. Этот ответ может создать впечатление, что двойное кодирование всегда неверно, и что вы можете просто исправить проблемы с кодированием, добавив столько вызовов кодирования / отмены кодирования, сколько необходимо, чтобы «заставить его работать». Это неправильно, и именно поэтому в первую очередь возникают ошибки кодирования. -1
Флориан Винтер
@FlorianWinter Я действительно не понимаю, где вы читаете это между строк. Можете ли вы помочь мне? (Пожалуйста, прочтите вопрос и мой ответ)
hek2mgl
7

Когда вы пытаетесь посетить локальное имя файла через браузер Firefox, вы должны принудительно использовать file:\\\протокол ( http://en.wikipedia.org/wiki/File_URI_scheme ), иначе firefox закодирует ваше пространство ДВАЖДЫ. Измените фрагмент html следующим образом:

<img src="C:\Documents and Settings\screenshots\Image01.png"/>

к этому:

<img src="file:\\\C:\Documents and Settings\screenshots\Image01.png"/>

или это:

<img src="file://C:\Documents and Settings\screenshots\Image01.png"/>

Затем firefox получает уведомление о том, что это локальное имя файла, и он правильно отображает изображение в браузере, правильно кодируя строку один раз.

Полезная ссылка: http://support.mozilla.org/en-US/questions/900466

Эрик Лещинский
источник
0

Следующий фрагмент кода решил мою проблему. Думал, что это может быть полезно другим.

var strEnc = this.$.txtSearch.value.replace(/\s/g, "-");
strEnc = strEnc.replace(/-/g, " ");

Вместо использования по умолчанию encodeURIComponentмоя первая строка кода преобразует все spacesв hyphensиспользование шаблона регулярного выражения, /\s\gа следующая строка просто выполняет обратное, т.е. преобразует все hyphensобратно в spacesиспользование другого regex pattern /-/g. Вот /gсобственно и отвечает за finding allсоответствие символов.

Когда я отправляю это значение в свой вызов Ajax, оно проходит как normal spacesили просто %20и, таким образом, избавляется от double-encoding.

Субрата Саркар
источник
1
Я предполагаю, потому что вы не решаете проблему, а просто прикрываете ее - основная причина, что она все еще где-то там, и вы выполняете двойную работу (где-то вы случайно кодируете дважды, а где-то еще вы декодируете вручную, чтобы покрыть это вверх). Предполагая, что вы хотите делать что-то «правильно», лучше всего отладить и найти настоящего виновника.
Ник Андриопулос,
На самом деле решение работало для меня везде, где у меня возникала эта проблема. Так что я написал.
Субрата Саркар
2
@NiladriSarkar то, что hexbolt пытался сказать, заключается в том, что, хотя ваш код работает, это не жизнеспособное решение, а скорее грязное исправление, и его следует избегать ...
2Dee
-1

Попробуй это?

encodeURIComponent('space word').replace(/%20/g,'+')

Hopefulee
источник
1
Добро пожаловать в StackOverflow! Обычно ответы более полезны, если они включают некоторое объяснение того, почему ваше предложение решит проблему OP, а не просто фрагмент кода. Кроме того, поскольку на этот вопрос уже есть принятый ответ, было бы неплохо добавить некоторые пояснения, почему ваш ответ более правильный, чем этот.
DaveyDaveDave