В чем разница между URI.escape
и CGI.escape
и какой из них я должен использовать?
Какая разница между URI.escape и CGI.escape?
Ответ 1
Были небольшие различия, но важно то, что URI.escape
был устарел в Ruby 1.9.2... поэтому используйте CGI::escape
или ERB:: Util.url_encode.
Существует длинная дискуссия на ruby-core для тех, кого интересует, которая также упоминает WEBrick:: HTTPUtils.escape и WEBrick:: HTTPUtils.escape_form.
Ответ 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 ошибочен на уровне спецификации. Итак, мы не будет обеспечивать точную замену. Замена будет отличаться использование случай.
К сожалению, в документах нет ни одного слова об этом, единственный способ узнать об этом - проверить источник или запустить 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?"
Ответ 3
URI.escape принимает второй параметр, который позволяет вам отметить, что небезопасно. См. APIDock:
Ответ 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 для отдельных ключей и значений, прежде чем объединять их с '&' и добавлять их после '?'.