2011-04-09 39 views
0

錯編碼字符當我做了以下內容:解決與Java的URL給我的網址

try { 
    URL url = new URL(urlAsString); 
    //using proxy may increase latency 
    HttpURLConnection hConn = (HttpURLConnection) url.openConnection(Proxy.NO_PROXY); 
    // force no follow 
    hConn.setInstanceFollowRedirects(false); 
    // the program doesn't care what the content actually is  
    hConn.setRequestMethod("HEAD"); 
    // default is 0 => infinity waiting 
    hConn.setConnectTimeout(timeout); 
    hConn.setReadTimeout(timeout); 
    hConn.connect(); 
    int responseCode = hConn.getResponseCode(); 
    hConn.getInputStream().close(); 
    if (responseCode == HttpURLConnection.HTTP_OK) 
     return urlAsString; 

    String loc = hConn.getHeaderField("Location"); 
    if (responseCode == HttpURLConnection.HTTP_MOVED_PERM && loc != null) 
     return loc.replaceAll(" ", "+"); 

} catch (Exception ex) { 
} 
return ""; 
該URL

http://bit.ly/gek1qK我越來越

http://blog.tweetsmarter.com/twitter-downtime/twitter-redesignsâthen-一切 - 打破/

這是錯誤的。火狐解析

http://blog.tweetsmarter.com/twitter-downtime/twitter-redesigns%E2%80%94then-everything-breaks/

什麼是錯誤的代碼?

回答

3

根據RFC 2616, section 2.2,HTTP標頭值通常應使用ISO-8859-1進行編碼。

在這裏,bit.ly發送了一個錯誤的響應 - Location:標頭使用UTF-8編碼,所以em-dash字符由三個單獨的字節(0xe2,0x80,0x94)表示。

HttpURLConnection器,使用ISO-8859-1字節,使他們成爲三個字符(â和兩個不確定的字符),但它看起來使用UTF-8(生產每字符2個字節,如果你重新編碼它們,因爲在應用URL編碼之前,所有三個值均>> 0x80)。

Firefox很可能將數據視爲整個ISO-8859-1;該問題會在稍後應用URL編碼時自行消除。

您可以通過對URL編碼getHeaderField()返回的值執行相同的操作;由於Unicode的範圍U + 0080到U + 00FF是相同的ISO-8859-1字節範圍0x80-0xFF,所述非ASCII字符可以通過鑄造它們進行編碼,以int值:

/** 
* Takes a URI that was decoded as ISO-8859-1 and applies percent-encoding 
* to non-ASCII characters. Workaround for broken origin servers that send 
* UTF-8 in the Location: header. 
*/ 
static String encodeUriFromHeader(String uri) { 
    StringBuilder sb = new StringBuilder(); 

    for(char ch : badLocation.toCharArray()) { 
     if(ch < (char)128) { 
      sb.append(ch); 
     } else { 
      // this is ONLY valid if the uri was decoded using ISO-8859-1 
      sb.append(String.format("%%%02X", (int)ch)); 
     } 
    } 

    return sb.toString(); 
} 
+0

我是否需要爲位置應用網址編碼? – Karussell 2011-04-10 07:49:48

+0

順便說一句:我應用編碼意外。我將url複製到Firefox的url欄中,然後從那裏粘貼到這個問題中。 Firefox應用了編碼...我在post – Karussell 2011-04-10 07:51:53

+0

@SimonJ中修復了這個問題,所以我應該向bit.ly提交一個錯誤報告,或者這可以修復得不同嗎? – Karussell 2011-04-10 07:54:12

1

沒有什麼不對。不同之處在於不同編碼中的m-Dash表示方式不同。所以,如果Firefox使用的不是你的程序的編碼,你會看到不同的字符。

這兩個都是正確的,在你的情況。這只是編碼的問題。在Java中,您使用UTF-8,它是World Wide Web Consortium Recommendation;而看起來你在FF中看到的是ISO-8859。

如果要產生相同的結果,火狐在Java中,試試這個:

System.out.print(URLEncoder.encode(loc.replace(" ", "+"), "ISO-8859-1")); 

這將打印您在Firefox中看到。 (顯然,它將編碼/:,但只是爲了演示)

+0

它實際上的另一邊。不正確的一個在ISO8859-1(或CP1252)中編碼,正確的一個使用UTF-8編碼。 – BalusC 2011-04-09 13:38:31

+0

@BalusC嗯......我沒有得到你,我說的是UTF-8是推薦的 - 這是正確的。 FF可能使用平臺相關編碼。 – Nishant 2011-04-09 13:43:56

+0

我是的,我記得ISO-8859-1被定義在HTTP1.0標準的某個地方...... – Karussell 2011-04-09 13:59:18