2012-04-28 54 views
3

我有一個Javascript小書籤,它使用encodeURIcomponent將當前頁面的URL傳遞給服務器端,然後在服務器端使用urldecode來獲取字符。什麼是對URIcomponent非UTF-8字符進行編碼並對其進行解碼的正確方法?

問題是,當編碼字符不在utf-8中(對於我的情況,它是gb2312,但它可能是其他內容),並且當服務器執行urldecode時,解碼後的字符變爲正方形。顯然,這不是編碼之前的樣子。

這是一個小書籤,輸入可以是任何東西,所以我不能在js中定義「encode as gb2312」,或者在php腳本中「解碼爲gb2312」。

那麼,有沒有一種正確的方式使用encodeURIcomponent它將字符編碼和內容一起傳遞,然後解碼可以選擇正確的編碼來解碼它?

回答

0

對於瀏覽器的編碼,特別是對GB2312字符集,請檢查下面的文檔(在中國)第一

對於你的情況,%C8%B7%B6%A8實際上是從生成GB2312形式'\u786e\u5b9a'。當用戶直接在地址欄中輸入中文字符時,這種情況通常發生在IE和FF的(舊版本)版本上:
您使用的頁面內容中的非標準鏈接沒有執行IRI到URI編碼所有,只是渲染二進制字符串,如'/tag/\xc8\xb7\xb6\xa8'(douban.com曾經有這種用法標籤,現在他們使用正確的UTF8 URI編碼)。不太確定,因爲無法在Chrome中重現,也許在FF和IE中測試,關於部分的部分是真的。

其實,encodeURIComponent正確的輸出應該是

> encodeURIComponent('%C8%B7%B6%A8') 
    "%25C8%25B7%25B6%25A8" 

因此,在服務器端,當加引號的字符串包含非ASCII字節,你最好離開這個字符串,因爲它是,這裏'%C8%B7%B6%A8'

此外,您還可以檢查在客戶端再次在包含%XX其中XX比0x7F大的值適用encodeURIComponent。但我不確定這是否違反RFC 2396。

寫英文好累啊,不過還是要入鄉隨俗〜

+0

不錯源,我會檢查出來:) – lazycai 2012-05-02 07:13:40

0

使用escape(),然後將它們發送到服務器之前的字符numeric character reference翻譯。

MDN escape() reference

的十六進制形式的字符,其代碼單元值爲0xFF或 以下,是一個兩位數轉義序列:%XX。對於使用 更大的代碼單位的字符,將使用四位數格式%uxxxx。

因此,很容易通過使用簡單replace()語句的escape()輸出以數字字符參考翻譯:

escape(input_value).replace(/%u([0-9a-fA-F]{4})/g, '&#x$1;'); 

或者,如果你的服務器端語言只支持十進制實體,用途:

escape(input_value).replace(/%u([0-9a-fA-F]{4})/g, function(m0, m1) { 
       return '&#' + parseInt(m1, 16) + ';'; 
}; 

實施例的代碼PHP

client.html(文件編碼:GB2312)

<html> 
    <head> 
    <meta charset="gb2312"> 
    <script> 
    function processForm(form) { 
     console.log('BEFORE:', form.test.value); 
     form.test.value = escape(form.test.value).replace(/%u(\w{4})/g, function(m0, m1) { 
      return '&#' + parseInt(m1, 16) + ';'; 
     }); 
     console.log('AFTER:', form.test.value); 
     return true; 
    } 
    </script> 
    </head> 
    <body> 
    <form method="post" action="server.php" onsubmit="return processForm(this);"> 
     <input type="text" name="test" value="確定"> 
     <input type="submit"> 
    </form> 
    </body> 
</html> 

server.php

<?php 
echo '<script>console.log("', 
    $_REQUEST['test'], ' --> ', 
    mb_decode_numericentity($_REQUEST['test'], array(0x80, 0xffff, 0, 0xffff), 'UTF-8'), 
    '");</script>'; 
?> 
相關問題