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?

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

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

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

URI.escape était censé encoder une chaîne (URL) dans ce que l’on appelle un ” encodage en pourcentage “.

CGI::escape provient de la spécification CGI , qui décrit comment les données doivent être encodé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 été marqué comme obsolète:

De plus, URI.encode actuel est simple gsub. Mais je pense qu’il devrait diviser un URI en composants, puis échapper à chaque composant et enfin les rejoindre.

Donc, URI.encode actuel est considéré comme dangereux et obsolète. Cela sera supprimé ou modifier radicalement le comportement.

Quel est le remplacement en ce moment?

Comme je l’ai dit plus haut, le code URI.encod actuel est incorrect au niveau des spécifications. Nous ne fournirons donc pas le remplacement exact. Le remplacement variera selon son cas d’utilisation.

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

Malheureusement, il n’y a pas un seul mot à ce sujet dans les documents, la seule façon de le savoir est de vérifier le source ou d’exécuter le script avec des avertissements au niveau détaillé ( -wW2 ) (ou d’utiliser Google-fu).

Certains ont proposé d’utiliser CGI::Escape pour les parameters de requête, car vous ne pouviez pas échapper à un URI entier:

 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 ne doit être utilisé que pour les parameters de requête, mais les résultats seront, à nouveau, contre la spécification. En fait, le cas d’utilisation le plus courant consiste à échapper des données de formulaire, par exemple lors de l’envoi d’une application/x-www-form-urlencoded POST d’ application/x-www-form-urlencoded .

Aussi mentionné WEBrick::HTTPUtils.escape ne fait pas beaucoup d’amélioration (encore une fois, c’est juste un simple gsub , c’est-à-dire IMO, et même une option 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 à # , et c’est le comportement attendu. vous souhaitez conserver le hash # dans le chemin URI mais pas dans la requête URI.

Le seul problème qui rest est que nous n’avons pas échappé correctement à nos parameters de requête, ce qui nous amène à la conclusion: nous ne devrions pas utiliser une seule méthode pour l’URI complet, car il n’ya pas de solution parfaite (jusqu’à présent). Comme vous le voyez & n’a pas été échappé de “Mon blog et votre blog”. Nous devons utiliser une autre forme d’échappement pour les parameters de requête, où les utilisateurs peuvent mettre différents caractères ayant une signification particulière dans les URL. Entrez le code URL. L’encodage d’URL 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à demandé

 uri = Addressable::URI.parse("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:

  • N’utilisez pas URI.escape ou similaire
  • Utilisez CGI::escape si vous avez uniquement besoin d’échapper à un formulaire
  • Si vous avez besoin de travailler avec des URI, utilisez Addressable, cela offre un encodage d’URL, un encodage de formulaire et une normalisation des URL.
  • S’il s’agit d’un projet Rails, consultez ” Comment échapper à une chaîne dans Rails? ”

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

CGI::escape est bon pour échapper un segment de texte afin qu’ils puissent être utilisés dans les parameters de requête url (chaînes après ‘?’). Par exemple, si vous voulez avoir un paramètre contenant des barres obliques dans l’URL, CGI :: échappe d’abord à cette chaîne, puis l’insère 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 bon pour échapper à une URL qui n’a pas été échappée correctement. Par exemple, certains sites Web affichent une URL incorrecte / non échappée dans leur balise d’ancrage. Si votre programme utilise ces URL pour récupérer plus de ressources, OpenURI se plaindra que les URL ne sont pas valides. Vous devez URI::escape ceux-ci pour en faire une URL valide. Il est donc utilisé pour échapper à toute la chaîne URI pour la rendre correcte. Dans mon mot, URI :: unescape rend une URL lisible par l’homme, et URI :: escape le rend valide pour les navigateurs.

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

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"