¿Cuál es la diferencia entre URI.escape
y CGI.escape
y cuál debería usar?
¿Cuál es la diferencia entre URI.escape
y CGI.escape
y cuál debería usar?
Respuestas:
Hubo algunas pequeñas diferencias, pero el punto importante es que URI.escape
ha quedado en desuso en Ruby 1.9.2 ... así que use CGI::escape
o ERB :: Util.url_encode .
Hay una larga discusión sobre ruby-core para aquellos interesados que también menciona WEBrick :: HTTPUtils.escape y WEBrick :: HTTPUtils.escape_form .
ERB::Util.url_encode
correctamente%20
¿Cuál es la diferencia entre un hacha y una espada y cuál debo usar? Bueno, depende de lo que necesites hacer.
URI.escape
se suponía que codificaba una cadena (URL), llamada " codificación porcentual ".
CGI::escape
proviene de la especificación CGI , que describe cómo se deben codificar / decodificar los datos entre el servidor web y la aplicación.
Ahora, supongamos que necesita escapar de un URI en su aplicación. Es un caso de uso más específico. Para eso, la comunidad Ruby solía usarla URI.escape
durante años. El problema con URI.escape
era que no podía manejar la especificación 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
fue marcado como obsoleto:
Además, URI.encode actual es gsub simple. Pero creo que debería dividir un URI en componentes, luego escapar de cada componente y finalmente unirlos.
Por lo tanto, URI.encode actual se considera dañino y obsoleto. Esto será eliminado o cambiará drásticamente el comportamiento.
¿Cuál es el reemplazo en este momento?
Como dije anteriormente, el URI.encode actual es incorrecto en el nivel de especificación. Por lo tanto, no proporcionaremos el reemplazo exacto. El reemplazo variará según su caso de uso.
Desafortunadamente, no hay una sola palabra al respecto en los documentos, la única forma de saberlo es verificar la fuente o ejecutar el script con advertencias en el nivel detallado ( -wW2
) (o usar algún google-fu).
Algunos propusieron usar CGI::Escape
para los parámetros de consulta, porque no podía escapar de un URI completo:
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
debe usarse solo para parámetros de consulta, pero los resultados serán, nuevamente, contra la especificación. En realidad, el caso de uso más común es el escape de datos de formulario, como al enviar una application/x-www-form-urlencoded
solicitud POST.
También se menciona WEBrick::HTTPUtils.escape
que no hay mucha mejora (de nuevo, es solo una simple gsub
, que es, IMO, incluso una opción peor que 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"
La más cercana a la especificación parece ser la gema direccionable :
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"
Tenga en cuenta que, a diferencia de todas las opciones anteriores, Addressable no se escapa #
, y este es el comportamiento esperado. desea mantener el #
hash en la ruta URI pero no en la consulta URI.
El único problema que queda es que no escapamos de nuestros parámetros de consulta correctamente, lo que nos lleva a la conclusión: no debemos usar un solo método para todo el URI, porque no existe una solución perfecta (hasta ahora). Como ves &
, no se escapó de "Mi blog y tu blog". Necesitamos usar una forma diferente de escape para los parámetros de consulta, donde los usuarios pueden poner diferentes caracteres que tienen un significado especial en las URL. Ingrese la codificación URL. La codificación de URL debe usarse para cada valor de consulta "sospechoso", similar a lo que ERB::Util.url_encode
hace:
ERB::Util.url_encode "My Blod & Your Blog"
# => "My%20Blod%20%26%20Your%20Blog""
Es genial, pero ya hemos requerido Direccionable:
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"
Conclusión:
URI.escape
o similarCGI::escape
si solo necesita escapar de formaAddressable
una de sus gemas, primero puede analizar URL, fi rubydoc.info/gems/addressable/Addressable/URI.heuristic_parse
Addressable:URL
, luego puede llamar a todos los métodos de instancia en él, tal vez uno de ellos obtendrá los resultados deseados: rubydoc.info/gems/addressable/Addressable/URI
URI.escape toma un segundo parámetro que le permite marcar lo que no es seguro. Ver APIDock:
CGI::escape
es bueno para escapar del segmento de texto para que puedan usarse en los parámetros de consulta de URL (cadenas después de '?') Por ejemplo, si desea que el parámetro contenga caracteres de barra diagonal en la url, CGI :: escapa primero de esa cadena y luego insértela en la url.
Sin embargo, en Rails probablemente no lo usarás directamente. Usualmente lo usas hash.to_param
, lo que usarás CGI::escape
debajo del capó.
URI::escape
es bueno para escapar de una URL que no se escapó correctamente. Por ejemplo, algunos sitios web muestran una URL incorrecta / sin escape en su etiqueta de anclaje. Si su programa usa estas URL para obtener más recursos, OpenURI se quejará de que las URL no son válidas. Necesita URI::escape
estos para que sea una URL válida. Por lo tanto, se utiliza para escapar de toda la cadena URI para que sea adecuada. En mi palabra, URI :: unescape hace que una url sea legible por humanos, y URI :: escape lo hace válido para los navegadores.
Estos son los términos de mi laico y no dude en corregirlos.
La diferencia es que URI.escape no funciona ...
CGI.escape"/en/test?asd=qwe"
=> "%2Fen%2Ftest%3Fasd%3Dqwe"
URI.escape"/en/test?asd=qwe"
=> "/en/test?asd=qwe"
CGI.escape es para escapar de un valor de URL en la cadena de consulta. Todos los personajes que no caen en ALFA, DÍGITO, '_', '-', '.' y '' el conjunto de caracteres se escapa.
Pero eso haría que una URL sea incorrecta, ya que una url debe tener '/', ':', '?', '[', '&', '=' Y ';'. Quizás más de lo que no puedo pensar fuera de mi cabeza.
URI.escape deja esos caracteres de URL solos e intenta encontrar las claves de cadena de consulta y los valores para escapar. Sin embargo, esto realmente no se puede depender ya que los valores pueden tener todo tipo de caracteres que impiden un escape fácil. Básicamente, es demasiado tarde. Pero si se puede confiar en que la URL sea simple (no '&' sy '=' s, etc. en los valores), esta función podría usarse para escapar de caracteres ilegibles o ilegibles.
En general, use siempre CGI.escape en las claves y valores individuales antes de unirlos con '&' y agregarlos después de '?'.
CGI.escape no funcionó con la API OpenProject. Codificó el [] ,: y no el +. Pirateé esto juntos, lo que parece funcionar hasta ahora para la API de OpenProject. Pero estoy seguro de que le faltan algunos .gsub. Es probable que sea casi tan malo como URI.escape, pero no le dará los errores obsoletos.
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\"]")
Ambas salidas:
=> " http://test.com/some/path?query=[box:%20%22cart%22] "
=> " http://test.com/some/path?query=[box:%20 % 22cart% 22] "