115

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

一些有趣的例子:

心脏字符。如果我在浏览器中输入:

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

然后复制粘贴,我看到了这个网址

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 解码。

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

4

5 回答 5

69

我总是用 UTF-8 编码。从百分比编码的维基百科页面

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

似乎因为过去还有其他公认的 URL 编码方法,浏览器尝试了几种解码 URI 的方法,但如果你是编码的人,你应该使用 UTF-8。

于 2009-05-27T02:18:55.170 回答
10

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

如果您只是在 URL 栏中输入 URL,则浏览器没有可处理的基本页面,因此只能猜测。因此,在这种情况下,它似乎一直在执行 utf-8(因为您的两个输入都产生了三个八位字节形式的值)。

可悲的事实是,AFAIK 对于查询字符串中的值或 URL 中的任何字符应该解释为什么字符集没有标准。至少在查询字符串中的值的情况下,没有理由假设它们一定对应于字符。

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

于 2009-05-27T22:13:03.387 回答
9

IRI ( RFC 3987 ) 是取代 URI/URL(RFC 3986和更早版本)标准的最新标准。URI/URL 本身并不支持 Unicode(好吧,RFC 3986增加了未来基于 URI/URL 的协议的规定以支持它,但不更新过去的 RFC)。"%uXXXX" 方案是在某些情况下允许 Unicode 的非标准扩展,但并非所有人都普遍实施。另一方面,IRI 完全支持 Unicode,并要求在进行百分比编码之前将文本编码为 UTF-8。

于 2009-06-19T22:22:23.377 回答
6

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

取而代之的是,您指定一个 IRI,它会在上网时转换为一个 URI。

于 2010-04-14T05:31:36.433 回答
0

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

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

于 2009-05-27T16:08:32.577 回答