PHP错误的utf-8解码json字符串时使用javascript发布


PHP malformed utf-8 when decoding json string posted using javascript

我正在一个项目中工作,我不能修改PHP代码。我只能修改JavaScript,因为我在写它。

我将包含UTF-8字符的十六进制编码数据发布到PHP脚本中。当PHP脚本尝试将数据解码为JSON时。decode函数返回null并得到以下错误"格式错误的UTF-8字符,可能编码错误"。

十六进制解码似乎修改了编码,例如法语句子

L ' cvquitation en France est le troisi me sport en nombre de licencisamis

将被转换为:

L'x18 quitation en France est le troisime sport en nombre de

对于阿拉伯语句子或任何使用非拉丁字符的语言来说,情况更糟,因为它不再可读。

有什么事情,我可以做的Javascript部分来解决这个问题。也许在将句子转换为HEX之前进行某种转换以保存句子?

他是一个代码简单的演示问题:

PHP代码:

if(!empty($_POST)){
    print_r($_POST);
    $data = Hex2String($_POST["data"]);
    $result = json_decode($data, true);
    $errors = json_last_error();
    echo "Errpr: {$errors}<br />";
    var_dump($result);
    exit();
}
function Hex2String($hex){
    $string='';
    for ($i=0; $i < strlen($hex)-1; $i+=2){
        $string .= chr(hexdec($hex[$i].$hex[$i+1]));
    }
    return $string;
}
JavaScript代码

    /***
     * Converts a string into a hex representation of the string.
     * @param {string} string
     * @returns {String}
     */
    function Str2Hex (tmp){
        var str = "";
        for (var i=0; i<tmp.length; i++)
            str += ("00" + (tmp.charCodeAt(i)).toString(16)).substr(-2);
        return (str);
    }
    $(function(){

        var data = {
            frenchText: "L‘équitation en France est le troisième sport en nombre de licenciés",
            germanText: "Das für sein karolingisches in Höxter",
            arabicText: "جانب من آثار مدينة جدارا اليونانيَّة"
        };

        $.post("index.php?DBGSESSID=1", {data:Str2Hex(JSON.stringify(data))},function(data) {
            console.log($("#result"));
            console.log(data);
            $("#result").html(data);
        });
    });

完整例子:

<?php
    if(!empty($_POST)){
        print_r($_POST);
        $data = Hex2String($_POST["data"]);
        $result = json_decode($data, true);
        $errors = json_last_error();
        echo "Errpr: {$errors}<br />";
        var_dump($result);
        exit();
    }
    function Hex2String($hex){
        $string='';
        for ($i=0; $i < strlen($hex)-1; $i+=2){
            $string .= chr(hexdec($hex[$i].$hex[$i+1]));
        }
        return $string;
    }
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
    <head>
        <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
        <title>index</title>
        <link rel="stylesheet" href="/css/master.css" type="text/css" media="screen" title="no title" charset="utf-8" />
        <script type="text/javascript" charset="utf-8" src="./js/jquery.js"></script>
    </head>
    <body>
        <div id="result">
        </div>
        <script type="text/javascript">

            /***
             * Converts a string into a hex representation of the string.
             * @param {string} string
             * @returns {String}
             */
            function Str2Hex (tmp){
                var str = "";
                for (var i=0; i<tmp.length; i++)
                    str += ("00" + (tmp.charCodeAt(i)).toString(16)).substr(-2);
                return (str);
            }
            $(function(){

                var data = {
                    frenchText: "L‘équitation en France est le troisième sport en nombre de licenciés",
                    germanText: "Das für sein karolingisches in Höxter",
                    arabicText: "جانب من آثار مدينة جدارا اليونانيَّة"
                };

                $.post("index.php?DBGSESSID=1", {data:Str2Hex(JSON.stringify(data))},function(data) {
                    console.log($("#result"));
                    console.log(data);
                    $("#result").html(data);
                });
            });
        </script>
    </body>
</html>

找到解决方案:

function forceUnicodeEncoding(string) {
    return unescape(encodeURIComponent(string));
}
data.frenchText = forceUnicodeEncoding(data.frenchText);
data.germanText = forceUnicodeEncoding(data.germanText);
data.arabicText = forceUnicodeEncoding(data.arabicText);

唯一的问题是unescape函数在JavaScript 1.5版本中已经被弃用了

来源:http://andre.arko.net/2012/09/18/force-encoding-in-javascript/