2012年9月28日 星期五

細談 URL 編碼 (Part II)

細談 URL 編碼 (Part II)

The following examples had been tested on Mozilla's Firefox and Microsoft's IE. The document is provided as is. You are welcomed to use it for non-commercial purpose.
Written by: 國立中興大學資管系呂瑞麟

請勿轉貼
看其他教材

Part I,我們使用了 Big5 來編寫 網頁。在這個部分,我們使用另一種常用的編碼 -- UTF-8 -- 來編寫網頁。 網頁內容幾乎跟 Part I 的測試網頁相同,幾個比較不一樣的地方:儲存 檔案的時候,記得要以 UTF-8 的編碼方式儲存;<meta> 標籤的 charset 要改成 UTF-8;遠端的 servlet 要改成 EchoUTF8。你可以 到這裡 看一下。


請在測試網頁上點一下"確定"按鈕。如果使用 Firefox,你應該會看到如下的畫面:

如果使用 IE,你應該會看到如下的畫面:

仔細觀察兩個畫面的異同之處:在畫面上方的紅色框框,Firefox 出現的是"老呂", 而 IE 出現的卻是 %E8%80%81%E5%91%82。雖然這個地方出現了差異,但是還好, 觀察輸出畫面的第二行以及第三行,結果卻是一致的;也就是說,雖然兩種瀏覽器 對於資料的呈現的處理方式不同,但是對於實質資料的傳遞卻是一致的,每一個 字元的內容(或者 16 進位數)沒有差異。我們需要再次確認的就是:"老呂" 的 UTF-8 是不是 6 個字元,而且內容分別是 E8 80 81 E5 91 82。以下顯示 notepad++ 的畫面:
一般畫面16 進位畫面

而且從畫面中,我們可以看出"老呂"的 UTF-8 編碼確實是由 6 個字元組成, 這跟 Part I 的 4 個字元不一樣。從 Part I 的討論以及說明,我們知道 雖然 Tomcat 以 ISO-8859-1 編碼處理 URL 資料,只要把資料轉成 UTF-8 就可以正確的 處理;這次使用的 servlet 為 EchoUTF8,其程式碼如下:
01  import javax.servlet.*;
02  import javax.servlet.http.*;
03  import java.io.*;
04
05  public class EchoUTF8 extends HttpServlet {
06    public void doGet(HttpServletRequest req, HttpServletResponse res)
07           throws ServletException, IOException {
08      PrintWriter output;
09
10      res.setContentType("text/html;charset=UTF-8");
11      output = res.getWriter();
12
13      StringBuffer buf = new StringBuffer();
14      buf.append("<html><head><title>\n");
15      buf.append("Echo Big5\n");
16      buf.append("</title></head><body>\n");
17
18      String data = req.getParameter("data");
19      String orig = data.length() + " ";
20      for(int i=0; i<data.length(); i++) {
21        int ch = (int)data.charAt(i);
22        orig = orig + "%" + Integer.toHexString(ch);
23      }
24      String out1 = new String(data.getBytes("ISO-8859-1"), "UTF-8");
25
26      buf.append("<h1>String: " + data + "</h1>\n");
27      buf.append("<h1>Hex Numbers: " + orig + "</h1>\n");
28      buf.append("<h1>UTF-8 Encoded: " + out1 + "</h1>\n");
29      buf.append("</body></html>\n");
30      output.println(buf.toString());
31
32      output.close();
33    }
34  }
EchoUTF8 跟 EchoBig5 主要不同的地方在於第 10 和 24 行綠色的部分。 請注意:在之前,我一直以為像第 24 行的用法是對字串的內容去進行 轉碼的動作(從 APIs 中閱讀時的誤解),其實從 Part I 和 Part II 的說明 以及範例,第 24 行的用法不是在轉碼,資料的內容(也就是 16 進位的數字) 並沒有改變,只是在處理該資料時,(以這個範例來說)是以 UTF-8 的方式來 使用。 從之前的討論,我們可以得到以下的結論:
  • 當設定網頁的編碼方式的時候(利用 <meta> 標籤),請選擇能夠 呈現網頁內容的編碼;以台灣常見的正體中文來說,可以選擇 Big5 或者 UTF-8。
  • 當網頁經由 <form> 標籤傳送中文資料到伺服器端的時候,Firefox 和 IE(其他的瀏覽器可以自行去測試)會將 URL 中的中文資料依照網頁的編碼 方式來 encode。
  • 如果伺服器端使用的是 Tomcat 5.5.x 版,其預設的解讀中文資料的方式 是以 ISO-8859-1 來進行,因此會顯示亂碼;再進一步處理(或者顯示、儲存) 資料之前,請先給予適當的編碼;也就是說,若網頁編碼為 Big5,請在伺服器端 轉成 Big5;若網頁編碼為 UTF-8,請在伺服器端的程式將其轉成 UTF-8。
瀏覽器部分的 URL 編碼已經說明完畢,那麼 Ajax 程式中使用的 XMLHttpRequest 物件是以哪一種方式來進行 URL 編碼呢?請繼續閱讀。
回到:Part I 繼續閱讀:Part III


Written by: 國立中興大學資管系呂瑞麟












沒有留言:

張貼留言