Какая разница между URI.escape и CGI.escape?

В чем разница между URI.escape и CGI.escape и какой из них я должен использовать?

Ответ 2

Какая разница между топором и мечом и какой из них я должен использовать? Ну, это зависит от того, что вам нужно делать.

URI.escape должен был кодировать строку (URL) в, так называемый, Percent-encoding".

CGI::escape исходит из спецификации CGI, которая описывает, как данные должны кодироваться/декодироваться между веб-сервером и приложением.

Теперь скажем, что вам нужно избежать URI в вашем приложении. Это более конкретный вариант использования. Для этого сообщество Ruby использовало URI.escape в течение многих лет. Проблема с URI.escape заключалась в том, что она не могла обрабатывать спецификацию RFC-3896.

URI.escape 'http://google.com/foo?bar=at#anchor&title=My Blog & Your Blog' 
# => "http://google.com/foo?bar=at%23anchor&title=My%20Blog%20&%20Your%20Blog"

URI.escape был отмечен как устаревший:

Кроме того, текущий URI.encode является простым gsub. Но я думаю, что это должно разделяйте URI на компоненты, затем выходите из каждого компонента и, наконец, присоединяйтесь к ним.

Таким образом, текущий URI.encode считается вредным и устаревшим. Это будет удалять или изменять поведение резко.

Что такое замена в это время?

Как я уже говорил, текущий URI.encode ошибочен на уровне спецификации. Итак, мы не будет обеспечивать точную замену. Замена будет отличаться использование случай.

https://bugs.ruby-lang.org/issues/4167

К сожалению, в документах нет ни одного слова об этом, единственный способ узнать об этом - проверить источник или запустить script с предупреждениями на подробном уровне (-wW2) (или использовать некоторые Google -fu).

Некоторый предложил использовать CGI::escape для параметров запроса, потому что вы не могли избежать полного URI:

CGI::escape 'http://google.com/foo?bar=at#anchor&title=My Blog & Your Blog'
# => "http%3A%2F%2Fgoogle.com%2Ffoo%3Fbar%3Dat%23anchor%26title%3DMy+Blog+%26+Your+Blog"

CGI::escape следует использовать только для параметров запроса, но результаты будут снова применяться к спецификации. На самом деле наиболее распространенным вариантом использования является экранирование данных формы, например, при отправке запроса application/x-www-form-urlencoded POST.

Также упоминается WEBrick::HTTPUtils.escape не много улучшается (опять же это просто простой gsub, который есть, IMO, даже худший вариант, чем URI.escape):

WEBrick::HTTPUtils.escape 'http://google.com/foo?bar=at#anchor&title=My Blog & Your Blog'
# => "http://google.com/foo?bar=at%23anchor&title=My%20Blog%20&%20Your%20Blog" 

Ближайшим к спецификации кажется Addressable gem:

require 'addressable/uri'
Addressable::URI.escape 'http://google.com/foo?bar=at#anchor&title=My Blog & Your Blog'
# => "http://google.com/foo?bar=at#anchor&title=My%20Blog%20&%20Your%20Blog"

Обратите внимание, что в отличие от всех предыдущих параметров Addressable не выходит за пределы #, и это ожидаемое поведение. вы хотите сохранить хэш # в пути URI, но не в запросе URI.

Единственная проблема заключается в том, что мы не смогли избежать наших параметров запроса, что приводит нас к выводу: мы не должны использовать один метод для всего URI, потому что нет идеального решения (пока). Как вы видите, & не удалось избежать из "Моего блога и вашего блога". Нам нужно использовать другую форму экранирования для параметров запроса, где пользователи могут помещать разные символы, которые имеют особое значение в URL-адресах. Введите URL-код. URL-код должен использоваться для каждого "подозрительного" значения запроса, аналогичного тому, что ERB::Util.url_encode делает:

ERB::Util.url_encode "My Blod & Your Blog"
# => "My%20Blod%20%26%20Your%20Blog""

Это круто, но мы уже требовали адресации:

uri = Addressable::URI.parse("http://www.go.com/foo")
# => #<Addressable::URI:0x186feb0 URI:http://www.go.com/foo>
uri.query_values = {title: "My Blog & Your Blog"}
uri.normalize.to_s
# => "http://www.go.com/foo?title=My%20Blog%20%26%20Your%20Blog"

Вывод:

  • Не используйте URI.escape или аналогичный
  • Используйте CGI::escape, если вам нужна только функция escape
  • Если вам нужно работать с URI, используйте Addressable, он предлагает кодировку URL, кодирование формы и нормализует URL-адреса.
  • Если это проект Rails, проверьте "Как удалить URL-адрес в Rails?"

Ответ 4

CGI::escape хорош для экранирования текстового сегмента, поэтому они могут использоваться в параметрах запроса url (строки после '?'). Например, если вы хотите иметь параметр, содержащий косые символы в URL-адресе, вы CGI:: сначала выполните эту строку, а затем вставьте ее в URL-адрес.

Однако в Rails вы, вероятно, не будете использовать его напрямую. Обычно вы используете hash.to_param, который будет использовать CGI::escape под капотом.


URI::escape хорош для экранирования URL-адреса, который не был экранирован должным образом. Например, некоторые веб-сайты выводят неверный/неэкранированный URL-адрес в свой якорный тег. Если ваша программа использует эти URL для получения дополнительных ресурсов, OpenURI будет жаловаться, что URL-адреса недействительны. Для этого нужно URI::escape сделать его действительным URL-адресом. Таким образом, он используется, чтобы избежать всей строки URI, чтобы сделать ее правильной. Мое слово URI:: unescape делает URL-адрес, доступный для чтения человеком, а URI:: escape делает его действительным для браузеров.

Это мой мирянин и не стесняйтесь исправить их.

Ответ 5

Разница в том, что URI.escape не работает...

CGI.escape"/en/test?asd=qwe"
=> "%2Fen%2Ftest%3Fasd%3Dqwe"

URI.escape"/en/test?asd=qwe"
=> "/en/test?asd=qwe"

Ответ 6

CGI.escape предназначен для экранирования значения URL в строке запроса. Все символы, которые не попадают в ALPHA, DIGIT, '_', '-', '.' и набор символов '' экранирован.

Но это сделало бы URL неверным, так как URL должен иметь '/', ':', '?', '[', '&', '=' И ';'. Возможно больше, что я не могу думать о макушке.

URI.escape оставляет эти символы URL в одиночестве и пытается найти ключи строки запроса и значения, которые нужно экранировать. Однако это действительно не может зависеть, так как значения могут иметь всевозможные символы, предотвращающие легкий выход. По сути, уже слишком поздно. Но если URL-адрес может быть простым (без '& and' = etc в значениях), эта функция может использоваться для экранирования, возможно, нечитаемых или недопустимых символов.

В общем, всегда используйте CGI.escape для отдельных ключей и значений, прежде чем объединять их с '&' и добавлять их после '?'.