web-dev-qa-db-fra.com

Quelle est la bonne façon de coder les caractères Unicode par URL?

Je connais le schéma non-standard% uxxxx mais cela ne semble pas un choix judicieux, car le schéma a été rejeté par le W3C.

Quelques exemples intéressants:

Le personnage de coeur. Si je tape ceci dans mon navigateur:

http://www.google.com/search?q=♥

Puis copiez et collez-le, je vois cette URL

http://www.google.com/search?q=%E2%99%A5

ce qui donne l'impression que Firefox (ou Safari) le fait.

urllib.quote_plus(x.encode("latin-1"))
'%E2%99%A5'

ce qui a du sens, sauf pour les choses qui ne peuvent pas être encodées en Latin-1, comme le caractère à trois points.

Si je tape l'URL

http://www.google.com/search?q=…

dans mon navigateur puis copier et coller, je reçois

http://www.google.com/search?q=%E2%80%A6

retour. Ce qui semble être le résultat de faire

urllib.quote_plus(x.encode("utf-8"))

ce qui a du sens puisque… ne peut pas être encodé avec Latin-1.

Mais alors, je ne vois pas comment le navigateur sait s'il doit décoder avec UTF-8 ou Latin-1.

Puisque cela semble être ambigu:

In [67]: u"…".encode('utf-8').decode('latin-1')
Out[67]: u'\xc3\xa2\xc2\x80\xc2\xa6'

fonctionne, donc je ne sais pas comment le navigateur calcule s'il doit décoder cela avec UTF-8 ou Latin-1.

Quelle est la bonne chose à faire avec les caractères spéciaux que je dois traiter?

106
Josh Gibson

Je voudrais toujours encoder en UTF-8. De la page Wikipedia sur l'encodage en pourcentage :

La syntaxe générique d’URI prescrit que les nouveaux schémas d’URI assurant la représentation des données de caractère dans un URI doivent, en réalité, représenter des caractères de l’ensemble non réservé sans traduction et doivent convertir tous les autres caractères en octets conformément à UTF-8, puis pourcentage encoder ces valeurs. Cette exigence a été introduite en janvier 2005 avec la publication de RFC 3986 . Les schémas d'URI introduits avant cette date ne sont pas affectés.

Il semble que, du fait qu'il existait d'autres méthodes acceptées de codage d'URL dans le passé, les navigateurs ont essayé plusieurs méthodes de décodage d'un URI, mais si vous codifiez vous-même, vous devez utiliser UTF-8.

63
John Biesnecker

La règle générale semble être que les navigateurs encodent les réponses au formulaire en fonction du type de contenu de la page à partir de laquelle le formulaire a été servi. Cela suppose que si le serveur nous envoie "text/xml; charset = iso-8859-1", il attend des réponses dans le même format.

Si vous entrez simplement une URL dans la barre d'URL, le navigateur n'a pas de page de base sur laquelle travailler et doit donc deviner. Donc, dans ce cas, il semble faire utf-8 tout le temps (puisque vos deux entrées ont produit des valeurs de forme à trois octets).

La triste vérité est que, autant que je sache, il n'y a pas de norme pour le caractère défini par les valeurs d'une chaîne de requête, ni même par les caractères de l'URL, qui doivent être interprétés comme. Au moins dans le cas des valeurs de la chaîne de requête, il n’ya aucune raison de supposer qu’elles correspondent nécessairement à des caractères.

L’un des problèmes connus est que vous devez indiquer à votre infrastructure de serveur le jeu de caractères dans lequel vous souhaitez que la chaîne de requête soit codée - par exemple, dans Tomcat, vous devez appeler request.setEncoding () (ou une méthode similaire) avant , vous appelez l’une des méthodes request.getParameter (). Le manque de documentation sur ce sujet reflète probablement le manque de prise de conscience du problème par de nombreux développeurs. (Je demande régulièrement à Java interviewés quelle est la différence entre un lecteur et un flux de sortie, et reçois régulièrement des regards vides)

9
araqnid

IRI ( RFC 3987 ) est la dernière norme qui remplace les normes URI/URL ( RFC 3986 et antérieures). Les adresses URI/URL ne supportent pas nativement Unicode (ainsi, RFC 3986 ajoute des dispositions pour les futurs protocoles basés sur URI/URL afin de le prendre en charge, mais ne met pas à jour les RFC antérieures). Le schéma "% uXXXX" est une extension non standard autorisant Unicode dans certaines situations, mais n'est pas universellement implémenté par tout le monde. D'autre part, IRI prend entièrement en charge les caractères Unicode et requiert que le texte soit codé au format UTF-8 avant d'être codé en pourcentage.

8
Remy Lebeau

Les adresses IRI ne remplacent pas les adresses URI, car seules les adresses URI (en pratique, ASCII) sont autorisées dans certains contextes, y compris HTTP.

Au lieu de cela, vous spécifiez un IRI et il est transformé en un URI lorsque vous vous connectez au réseau.

6
Mark Nottingham

La première question est quels sont vos besoins? Le codage UTF-8 est un très bon compromis entre la prise de texte créé avec un éditeur bon marché et la prise en charge d’une grande variété de langues. En ce qui concerne le navigateur identifiant le codage, la réponse (du serveur Web) doit indiquer au navigateur le codage. Néanmoins, la plupart des navigateurs tenteront de deviner, car cela manque ou est erroné dans de nombreux cas. Ils devinent, en lisant une partie du flux de résultat, s'il existe un caractère qui ne rentre pas dans le codage par défaut. Actuellement, tous les navigateurs (? Je n’ai pas vérifié cela, mais c’est assez proche de la vérité) utilisent utf-8 par défaut.

Utilisez donc utf-8 sauf si vous avez une raison impérieuse d'utiliser l'un des nombreux schémas de codage.

0
Pat O