对Unicode字符进行URL编码的正确方法是什么?

时间:2009-05-26 21:18:57

标签: unicode utf-8 character-encoding urlencode web-standards

我知道非标准%uxxxx方案,但这似乎不是明智的选择,因为该方案已被W3C拒绝。

一些有趣的例子:

心中的人物。 如果我在浏览器中输入:

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

然后复制并粘贴它,我看到了这个URL

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

这使得它看起来像Firefox(或Safari)正在这样做。

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

这是有道理的,除了那些不能用Latin-1编码的东西,比如三点字符。

如果我输入网址

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

进入我的浏览器然后复制并粘贴,我得

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

回。这似乎是做的结果

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

这是有道理的,因为...不能用Latin-1编码。

但后来我不清楚浏览器如何知道是用UTF-8还是Latin-1解码。

因为这似乎含糊不清:

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

有效,所以我不知道浏览器是如何用UTF-8或Latin-1解码的。

使用我需要处理的特殊字符做什么是正确的?

5 个答案:

答案 0 :(得分:61)

我总是用UTF-8编码。来自Wikipedia page on percent encoding

  

通用URI语法要求在URI中提供字符数据表示的新URI方案实际上必须表示来自未保留集的字符而不进行转换,并且应该根据UTF-8将所有其他字符转换为字节,然后对这些值进行百分比编码。该要求于2005年1月引入,RFC 3986出版。在此日期之前引入的URI方案不受影响。

似乎因为过去有其他可接受的URL编码方式,浏览器会尝试多种解码URI的方法,但如果你是编码的人,你应该使用UTF-8。

答案 1 :(得分:9)

一般规则似乎是浏览器根据表单的内容类型对表单响应进行编码。这是一个猜测,如果服务器发送给我们“text / xml; charset = iso-8859-1”,那么他们希望以相同的格式返回响应。

如果您只是在网址栏中输入网址,那么浏览器就没有可供使用的基页,因此只需要猜测。所以在这种情况下它似乎一直在做utf-8(因为你的输入都产生了三个八位字节的表格值)。

可悲的事实是,AFAIK没有标准用于将查询字符串中的值设置为什么字符,或者实际上URL中的任何字符都应该被解释为。至少在查询字符串中的值的情况下,没有理由认为它们必须对应于字符。

这是一个已知的问题,您必须告诉您的服务器框架您希望将查询字符串编码为哪个字符集 - 例如,在Tomcat中,您必须调用request.setEncoding()(或类似的方法) )之前调用任何request.getParameter()方法。关于这个主题的文档缺乏可能反映了许多开发人员对该问题缺乏认识。 (我经常向Java受访者询问Reader和InputStream之间的区别是什么,并且经常看起来是空白的)

答案 2 :(得分:7)

IRI(RFC 3987)是替换URI / URL(RFC 3986及更早版本)标准的最新标准。 URI / URL本身不支持Unicode(好吧,RFC 3986添加了对未来基于URI / URL的协议的支持,但不会更新过去的RFC)。 “%uXXXX”方案是在某些情况下允许Unicode的非标准扩展,但并非每个人都普遍实现。另一方面,IRI完全支持Unicode,并要求在进行百分比编码之前将文本编码为UTF-8。

答案 3 :(得分:6)

IRI不替换URI,因为在某些上下文中只允许使用URI(实际上是ASCII) - 包括HTTP。

相反,您指定一个IRI,并在线路上转换为URI。

答案 4 :(得分:0)

第一个问题是你的需求是什么?在使用便宜的编辑器创建文本和支持各种语言之间,UTF-8编码是一个非常好的折衷方案。关于识别编码的浏览器,响应(来自Web服务器)应该告诉浏览器编码。仍然大多数浏览器都会尝试猜测,因为在很多情况下这种情况要么丢失,要么错误。他们通过读取一些结果流来猜测是否存在不符合默认编码的字符。目前所有浏览器(?我没有检查过,但它非常接近真实)使用utf-8作为默认值。

因此,除非您有令人信服的理由使用其他许多编码方案之一,否则请使用utf-8。

相关问题