如何正确编码这个URL

我正在尝试使用JSoup来获取此URL

http://betatruebaonline.com/img/parte/330/CIGUEÑAL.JPG

即使使用编码,我也有一个例外。 我不明白为什么编码是错误的。 它返回

http://betatruebaonline.com/img/parte/330/CIGUEN%C3%91AL.JPG

而不是正确的

http://betatruebaonline.com/img/parte/330/CIGUEN%CC%83AL.JPG

我如何解决这个问题? 谢谢。

private static void GetUrl()
{
    try
    {
        String url = "http://betatruebaonline.com/img/parte/330/";
        String encoded = URLEncoder.encode("CIGUEÑAL.JPG","UTF-8");
        Response img = Jsoup
                            .connect(url + encoded)
                            .ignoreContentType(true)
                            .execute();

        System.out.println(url);
        System.out.println("PASSED");
    }
    catch(Exception e)
    {
        System.out.println("Error getting url");
        System.out.println(e.getMessage());
    }
}

编码没有错,这里的问题是复合unicode和预编码字符“Ñ”的Unicode可以用2种方式显示,它们看起来相同但是真的不同

precomposed unicode: Ñ           -> %C3%91
composite unicode: N and ~       -> N%CC%83

我强调,两者都是正确的,这取决于你想要哪种类型的unicode:

String normalize = Normalizer.normalize("Ñ", Normalizer.Form.NFD);
System.out.println(URLEncoder.encode("Ñ", "UTF-8")); //%C3%91
System.out.println(URLEncoder.encode(normalize, "UTF-8")); //N%CC%83

这里发生了什么?

正如@yelliver所说,webserver似乎在其路径名中使用了NFD编码的unicode。 所以解决方案是使用相同的编码。

网络服务器是否正确?

1.对于那些好奇的人(像我),这篇关于多语言Web地址的文章为这个主题带来了一些启发。 在关于IRI程序的部分(实际由网络服务器处理的部分)中,它指出:

尽管域名注册管理机构可以同意接受特定形式的域名和编码(基于ASCII码的punycode),但多脚本路径名称标识位于多种平台上的资源,这些平台的文件系统会继续使用许多不同的平台编码。 这使得路径比域名更难处理。

2.更多关于如何编码pathes受试者可以在5.3.2.2节中找到。 在IETF关于国际化资源标识符(IRIs)的建议标准rfc3987。 它说:

IRI的等价性必须依赖于IRI在适当的预字符标准化的假设,而不是在比较两个IRI时应用字符标准化。 例外情况是从非数字形式转换,以及从非基于UCS的字符编码转换为基于UCS的字符编码。 在这些情况下,使用NFC的NFC或标准化代码转换器必须用于互操作性。 为了避免错误的消极处理和代码转换问题, 应该使用NFC创建IRI 。 使用NFKC可能会避免更多问题; 例如,通过选择半角拉丁字母而不是全角字母,全角而不是半角片假名。

3. Unicode联盟指出:

NFKC是标识符的首选形式,特别是在存在安全问题的情况下(见UTR#36)。 NFD和NFKD对于内部处理最为有用。

结论

问题中提到的网络服务器不符合IRI标准或unicode联盟的建议,并使用NFD编码代替NFC或NFKC。 正确编码URL-String的一种方法如下

URI uri = new URI(url.getProtocol(), url.getUserInfo(), IDN.toASCII(url.getHost()), url.getPort(), url.getPath(), url.getQuery(), url.getRef());

然后将该Uri转换为ASCII字符串:

String correctEncodedURL=uri.toASCIIString(); 

toASCIIString()调用使用NFC编码的unicode的encode()IDN.toASCII()将主机名转换为Punycode。


非常简单的解决方案:编码系统提供,您需要的是不同的,以下解决方案将对您有所帮助。

private static void GetUrl(String url)
{
    try
    {

        String encodedurl = url.replace("Ñ","N%CC%83");
        Response img = Jsoup
                            .connect(encodedurl)
                            .ignoreContentType(true)
                            .execute();

        System.out.println(url);
        System.out.println("PASSED");
    }
    catch(Exception e)
    {
        System.out.println("Error getting url");
        System.out.println(e.getMessage());
    }
}
链接地址: http://www.djcxy.com/p/41131.html

上一篇: How to encode properly this URL

下一篇: PHP Get Site URL Protocol