Unicode 查询参数的 Punycode

Punycode for Unicode query parameter

我正在尝试使用 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

我做错了什么?

你用错了punycode。 Punycode用于域名,包括URL的域名部分

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

在 Java 中为此使用 java.net.URLEncoder.encodejava.net.URLDecoder.decode;为了获得可靠的结果,请使用编码名称为 "UTF-8".

的较新的 2-arg 形式