Відповіді:
Були деякі невеликі відмінності, але важливим моментом є те URI.escape
, що в Ruby 1.9.2 застаріло, тому використовуйте CGI::escape
або ERB :: Util.url_encode .
Існує тривала дискусія про ruby-core для зацікавлених, хто також згадує WEBrick :: HTTPUtils.escape і WEBrick :: HTTPUtils.escape_form .
ERB::Util.url_encode
яке належним чином використовується %20
для пробілів
Яка різниця між сокирою та мечем і яким я повинен користуватися? Ну, це залежить від того, що вам потрібно зробити.
URI.escape
повинен був кодувати рядок (URL) у, так званому, " кодуванні відсотків ".
CGI::escape
походить від специфікації CGI , яка описує, як дані повинні кодуватися / декодувати між веб-сервером та програмою.
Тепер скажімо, що вам потрібно уникнути URI у вашому додатку. Це більш конкретний випадок використання. Для цього громада Рубі використовувала 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.en є простим gsub. Але я думаю, що він повинен розділити URI на компоненти, потім вийти з кожного компонента і, нарешті, приєднатись до них.
Отже, поточний код URI.en вважається шкідливим та застарілим. Це буде видалено або змінить поведінку кардинально.
Що таке заміна на даний момент?
Як я вже говорив вище, поточний URI.encode неправильний на рівні специфікації. Тож ми не забезпечимо точну заміну. Заміна буде залежати від випадку використання.
На жаль, в документах немає жодного слова про це, єдиний спосіб дізнатися про нього - це перевірити джерело або запустити скрипт із попередженнями на рівні докладної (-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"
Найближчим до специфікації, здається, є Адресний дорогоцінний камінь:
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"
Зауважте, що на відміну від усіх попередніх параметрів, адреса не виходить #
, і це очікувана поведінка. ви хочете зберегти #
хеш у шляху 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
якщо вам потрібна лише форма втечіAddressable
один із своїх дорогоцінних каменів, ви можете спершу проаналізувати URL-адресу, fi rubydoc.info/gems/addressable/Addressable/URI.heuristic_parse
Addressable:URL
, потім ви можете викликати всі методи екземпляра на ньому, можливо, один з них отримає бажані результати: rubydoc.info/gems/addressable/Addressable/URI
URI.escape бере другий параметр, який дозволяє позначити, що небезпечно. Див. APIDock:
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 робить її дійсною для браузерів.
Це термін мого мирянина і сміливо виправляю їх.
Різниця полягає в тому, що URI.escape не працює ...
CGI.escape"/en/test?asd=qwe"
=> "%2Fen%2Ftest%3Fasd%3Dqwe"
URI.escape"/en/test?asd=qwe"
=> "/en/test?asd=qwe"
CGI.escape призначений для уникнення значення URL у рядку запиту. Усі символи, які не потрапляють у ALPHA, DIGIT, '_', '-', '.' та "" набір символів уникнути.
Але це призведе до неправильної URL-адреси, оскільки URL-адреса повинна мати "/", ":", "?", "[',' & ',' = 'І'; '. Можливо, більше того, що я не можу придумати з голови.
URI.escape залишає ці символи URL-адреси в спокої і намагається знайти рядки клавіш і значення для запиту, щоб вийти. Однак від цього насправді не можна залежати, оскільки значення можуть містити всілякі символи, що перешкоджають легкому виходу. В основному, це занадто пізно. Але якщо URL-адреса може залежати від простої (у значеннях немає '&' s та '=' і т. Д.), Ця функція може використовуватися для уникнення, можливо, нечитаних або незаконних символів.
Загалом - завжди використовуйте CGI.escape на окремих клавішах та значеннях, перш ніж з'єднувати їх із "&" та додавати їх після "?".
CGI.escape не працював з API OpenProject. Він кодував [],: а не +. Я зламав це разом, що, здається, працює досі для API OpenProject. Але я впевнений, що в ньому відсутні деякі .gsub. Це, мабуть, майже так само погано, як URI.escape, але це не дасть вам застарілих помилок.
class XXX
def self.encode(path)
path, query = path.split("?", 2)
return path if query.nil?
query = CGI.escape(query).gsub("%3A", ":").gsub("%3D","=").gsub("%5B","[").gsub("%5D","]").gsub("%2C",",").gsub("+","%20")
return [path,query].join("?")
end
end
XXX.encode("http://test.com/some/path?query=[box: \"cart\"]")
URI.encode("http://test.com/some/path?query=[box: \"cart\"]")
Обидва вихідні дані:
=> " http://test.com/some/path?query= evidencebox:%20%22cart%22] "
=> " http://test.com/some/path?query= evidencebox:%20 % 22карт.% 22] "