web-dev-qa-db-fra.com

Quelle est la différence entre URI.escape et CGI.escape?

Quelle est la différence entre URI.escape et CGI.escape et lequel dois-je utiliser?

130
Tom Lehman

Il y avait quelques petites différences, mais le point important est que URI.escape a été obsolète dans Ruby 1.9.2 ... utilisez donc CGI::escape ou ERB :: Util.url_encode .

Il y a une longue discussion sur Ruby-core pour les intéressés, qui mentionne également WEBrick :: HTTPUtils.escape et WEBrick :: HTTPUtils.escape_form .

113

Quelle est la différence entre une hache et une épée et celle que je devrais utiliser? Eh bien, il {dépend} _ de ce que vous devez faire.

URI.escape était censé encoder une chaîne (URL) dans, ainsi appelée " Pourcentage de codage ".

CGI::escape provient de la spécification CGI , qui décrit comment les données doivent être codées/décodées entre le serveur Web et l'application. 

Maintenant, disons que vous devez échapper à un URI dans votre application. C’est un cas d’utilisation plus spécifique . Pour cela, la communauté Ruby a utilisé URI.escape pendant des années. Le problème avec URI.escape était qu'il ne pouvait pas gérer la spécification 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 a été marqué comme obsolète:

De plus, URI.encode actuel est un simple gsub. Mais je pense que ça devrait diviser un URI en composants, puis échapper à chacun des composants et enfin rejoins-les.

Donc, URI.encode actuel est considéré comme dangereux et obsolète. Cette volonté être retiré ou changer radicalement de comportement.

Quel est le remplacement en ce moment?

Comme je l'ai dit plus haut, le code URI.encode actuel est incorrect au niveau des spécifications. Alors on ne fournira pas le remplacement exact. Le remplacement variera par son cas d'utilisation.

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

Malheureusement, il n'y a pas un seul mot à ce sujet dans la documentation, le seul moyen de le savoir est de vérifier le code source ou d'exécuter le script avec des avertissements de niveau verbeux (-wW2) (ou d'utiliser un outil google-fu).

Certains ont proposé d'utiliser CGI::Escape pour les paramètres de requête, car vous ne pouviez pas échapper à un URI complet:

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 doit être utilisé uniquement pour les paramètres de requête, mais les résultats seront, là encore, en regard de la spécification. En fait, le cas d'utilisation le plus courant est l'échappement de données de formulaire, par exemple lors de l'envoi d'une demande application/x-www-form-urlencoded POST.

Également mentionné, WEBrick::HTTPUtils.escape n’apporte guère d’amélioration (là encore, c’est une simple gsub, qui est, IMO, une option encore pire 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" 

Le plus proche de la spécification semble être le joyau adressable :

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"

Notez que contrairement à toutes les options précédentes, Addressable n'échappe pas à #, ce qui correspond au comportement attendu. vous souhaitez conserver le hash # dans le chemin de l'URI mais pas dans la requête URI.

Le seul problème qui reste est que nous n’avons pas échappé correctement à nos paramètres de requête, ce qui nous amène à la conclusion suivante: nous ne devrions pas utiliser une seule méthode pour l’URI entier, car il n’existe pas de solution parfaite (jusqu’à présent) . vous voyez & n'a pas été échappé de "Mon blog et votre blog". Nous devons utiliser une forme différente d'échappement pour les paramètres de requête, où les utilisateurs peuvent insérer différents caractères ayant une signification particulière dans les URL. Entrez l'URL encoder. L'URL encoder doit être utilisé pour chaque valeur de requête "suspecte", similaire à ce que fait ERB::Util.url_encode:

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

C'est cool mais nous avons déjà requis Addressable:

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"

Conclusion:

  • Ne pas utiliser URI.escape ou similaire
  • Utilisez CGI::escape si vous avez seulement besoin de sortir du formulaire.
  • Si vous devez travailler avec des URI, utilisez Addressable, il propose le codage d’URL, le codage de formulaire et la normalisation des URL.
  • S'il s'agit d'un projet Rails, consultez " Comment puis-je échapper à l'URL d'une chaîne dans Rails? "
196
Ernest

URI.escape prend un deuxième paramètre qui vous permet de marquer ce qui est dangereux. Voir APIDock:

http://apidock.com/Ruby/CGI/escape/class

http://apidock.com/Ruby/URI/Escape/escape

9
Robert Speicher

CGI::escape est utile pour échapper un segment de texte afin qu'il puisse être utilisé dans les paramètres de requête d'URL (chaînes après "?"). Par exemple, si vous souhaitez que les paramètres contenant des barres obliques dans l'URL, vous devez d'abord échapper CGI:, puis l'insérer dans l'URL. 

Cependant, dans Rails, vous ne l'utiliserez probablement pas directement. Habituellement, vous utilisez hash.to_param, qui utilisera CGI::escape sous le capot.


URI::escape est utile pour échapper à une URL qui n'a pas été échappée correctement. Par exemple, certains sites Web génèrent des URL erronées/non échappées dans leur balise d'ancrage. Si votre programme utilise ces URL pour récupérer plus de ressources, OpenURI se plaindra de l'invalidité des URL. Vous devez URI::escape ceux-ci pour en faire une URL valide. Donc, il est utilisé pour échapper à toute la chaîne d'URI afin de la rendre correcte. Dans mon Word, URI :: unescape rend une URL lisible par un humain, et URI :: escape la rend valide pour les navigateurs.

Ce sont les termes de mon profane et n'hésitez pas à les corriger.

6
lulalala

La différence est que URI.escape ne fonctionne pas ...

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

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

CGI.escape sert à échapper une valeur d'URL dans la chaîne de requête. Tous les caractères qui ne tombent pas dans les champs ALPHA, DIGIT, '_', '-', '.' et '' les jeux de caractères sont échappés.

Mais cela rendrait une URL incorrecte, car une url doit avoir '/', ':', '?', '[', '&', '=' Et ';'. Peut-être plus que je ne peux pas penser à la tête.

URI.escape laisse ces caractères d'URL seuls et tente de trouver les clés et les valeurs de la chaîne de requête à échapper. Cependant, on ne peut pas vraiment compter sur cela car les valeurs peuvent avoir toutes sortes de caractères empêchant une évasion facile. En gros, c'est trop tard. Mais si l'URL peut être considérée comme simple (pas de '&' et '=' dans les valeurs, etc.), cette fonction peut être utilisée pour échapper à des caractères illisibles ou illisibles.

En général, utilisez toujours CGI.escape sur les clés et les valeurs individuelles avant de les joindre avec '&' et de les ajouter après le '?'.

0
Gerard ONeill