2012-04-28 51 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>'; 
?> 
相关问题