Punycode для параметра запроса Unicode

Я пытаюсь закодировать некоторые URL-адреса Unicode с Punycode. Эти 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

Что я тут не так сделал?

1 ответ

Решение

То, что вы сделали неправильно, это использовать punycode. Punycode используется только для доменных имен, включая часть имени домена в URL.

Другие части URL, включая часть параметров запроса, используют Percent Encoding, также известную как кодировка URL или URI, и это то, что делает Chrome; это кодирует не-ASCII символы Unicode в UTF-8, а затем все октеты, которые не входят в ограниченное подмножество ASCII, используя знак процента (%) и две шестнадцатеричные цифры; октеты 80-FF, используемые UTF-8 для не-ASCII, всегда кодируются%. Чтобы быть точным, часть параметра запроса обычно и другие части иногда используют небольшой вариант, определенный для представления формы HTML как application/x-www-form-urlencoded; это кодирует пробел как знак плюса "+" вместо%20, что однозначно, потому что "+" уже находится в небезопасном наборе, поэтому кодируется как%2B.

В Java использовать java.net.URLEncoder.encode а также java.net.URLDecoder.decode за это; для получения достоверных результатов используйте более новые формы 2-arg с кодировкой "UTF-8".

Другие вопросы по тегам