3

我正在尝试使用 Punycode 对一些 Unicode URL 进行编码。这些 URL 有一个包含非 ASCII 字符的查询参数,例如:

https://en.wiktionary.org/w/index.php?title=Clœlia&printable=yes

问题是,当我尝试在 Java 中执行此操作时,生成的 URL 是错误的:

String link = "https://en.wiktionary.org/w/index.php?title=Clœlia&printable=yes";
link = IDN.toASCII(link);

// -> link = http://en.wiktionary.org/w/index.xn--php?title=cllia&printable=yes-hgf

如果我这样做,结果字符串是不同的(我不知道为什么),但也是错误的:

String link = "http://en.wiktionary.org/w/index.php?title=" + IDN.toASCII("Clœlia") + "&printable=yes";

// -> link = http://en.wiktionary.org/w/index.php?title=xn--cllia-ibb&printable=yes

如果我从 Chrome 复制地址并将其粘贴到这里,我会得到这个 URL,这就是我想要的:

https://en.wiktionary.org/w/index.php?title=Cl%C5%93lia&printable=yes

我在这里做错了什么?

4

1 回答 1

2

你做错的是使用punycode。Punycode 用于域名,包括 URL 的域名部分.

URL 的其他部分,包括查询参数部分,使用百分比编码,也称为 URL 编码或 URI 编码,这就是 Chrome 正在做的事情;这会将非 ASCII Unicode 字符编码为 UTF-8,然后使用百分号 (%) 和两个十六进制数字对不在 ASCII 有限子集中的所有八位字节进行编码;UTF-8 用于非 ASCII 的八位字节 80-FF 始终是 % 编码的。确切地说,查询参数部分通常和其他部分有时使用为 HTML 表单提交定义的轻微变体application/x-www-form-urlencoded:这会将空格编码为加号“+”而不是 %20,这是明确的,因为“+”已经在不安全集中,因此编码为 %2B。

在Java中使用java.net.URLEncoder.encodejava.net.URLDecoder.decode为此;为了获得可靠的结果,请使用编码名称为“UTF-8”的较新的 2-arg 形式。

于 2015-06-19T06:34:56.910 回答