Почему URI.escape не скрывает одиночные кавычки?

Почему URI.escape избежать одиночных кавычек?

URI.escape("foo'bar\" baz")
=> "foo'bar%22%20baz"

Ответ 1

По той же причине он не убегает ? или / или : и т.д. URI.escape() только экранирует символы, которые не могут использоваться в URL-адресах вообще, а не символы, имеющие особое значение.

То, что вы ищете, CGI.escape():

require "cgi"
CGI.escape("foo'bar\" baz")
=> "foo%27bar%22+baz"

Ответ 2

Это старый вопрос, но ответ не был обновлен в течение длительного времени. Я думал, что обновляю это для других, у кого такая же проблема. Решение, которое я нашел, было опубликовано здесь: используйте ERB::Util.url_encode, если у вас есть модуль erb. Это помогло мне одинарные кавычки и * для меня.

CGI::escape не позволяет избежать пробелов правильно (%20) против знаков плюс.

Ответ 3

В соответствии с документами URI.escape(str [, unsafe]) использует регулярное выражение, соответствующее всем символам, которые необходимо заменить на коды. По умолчанию метод использует REGEXP:: UNSAFE. Когда этот аргумент является String, он представляет собой набор символов.

В вашем случае, чтобы изменить URI.escape, чтобы избежать даже одиночных кавычек, вы можете сделать что-то вроде этого...

reserved_characters = /[^a-zA-Z0-9\-\.\_\~]/
URI.escape(YOUR_STRING, reserved_characters)

Объяснение: Некоторая информация о спецификации...

Все имена и значения параметров экранируются с помощью [rfc3986] процентного кодирования (% xx). Символы не в безоговорочном набор символов ([rfc3986] раздел 2.3) должен быть закодирован. символов в незарезервированный набор символов не должен быть закодирован. шестнадцатеричный символы в кодировках должны быть в верхнем регистре. текстовые имена и значения должны кодироваться как октеты utf-8 перед процентным кодированием их на [rfc3629].

Ответ 4

Я знаю, что на это был дан ответ, но то, что я хотел, было чем-то немного отличающимся, и я подумал, что мог бы также опубликовать его: я хотел сохранить "/" в URL-адресе, но избежать всех других нестандартных персонажи. Я сделал это так:

#public filename is a *nix filepath, 
#like `"/images/isn't/this a /horrible filepath/hello.png"`

public_filename.split("/").collect{|s| ERB::Util.url_encode(s)}.join("/")
=> "/images/isn%27t/this%20a%20/horrible%20filepath/hello.png"

Мне нужно было избежать одиночной кавычки, поскольку я писал о недействительности кеша для AWS Cloudfront, которая не нравилась одиночным кавычкам и ожидала, что они будут экранированы. Вышеприведенное должно сделать uri, который более безопасен, чем стандартный URI.escape, но который по-прежнему выглядит как URI (CGI Escape прерывает формат uri, ускоряя "/" ).