代码之家  ›  专栏  ›  技术社区  ›  Vivin Paliath

jquery-ajax调用使字符编码混乱

  •  7
  • Vivin Paliath  · 技术社区  · 14 年前

    我有一个输出JSON的servlet。servlet的输出编码是ISO-8859-1。我们的webapp中的页面也设置为iso-8859-1。我会使用UTF-8,但这超出了我的控制范围;我们必须使用ISO-8859-1。

    当我自己点击servlet时,我可以看到已经输出的JSON数据。字符编码是正确的,所有字符看起来都不奇怪。

    但是,当我通过Ajax调用servlet并使用检索到的数据填充一个选择框时,我得到来代替(看起来)所有有重音的字符(例如,我有重重音或锐重音、dieresis或扬抑符)。当我在Firebug下的网络选项卡中查看响应时,我可以看到文本看起来很好。但是,当我使用这些数据填充选择框时,会得到带有questionmark的菱形。

    这些字符都是有效的ISO-8859-1字符,所以我不明白它们为什么不能正确显示。

    编辑

    更多信息。我用 GET 在里面 jQuery.ajax 我已经定好了 scriptCharset ISO-8859-1 . 在服务器端,我已经使用 request.setCharacterEncoding("ISO-8859-1");

    编辑

    代码示例:

    这是我目前拥有的。我补充说 scriptCharset: "ISO-8859-1" 没有效果。

            jQuery.ajax({
                url: "/countryAndProvinceCodeServlet",
                data: data,
                dataType: "json",
                type: "GET",
                success: function(data) {
                   ...
                },
            });
    

    我的servlet使用 org.json.JSONObject 只需通过执行 response.getWriter().print(jsonObject.toString());

    更新

    根据关于JSON的注释以及它应该如何成为UTF-8,我试图查看是否可以将数据作为文本(所以设置 dataType text 在里面 阿贾克斯 )然后自己将其评估为JSON(在JavaScript中)。这似乎也不管用!当我这样做的时候 console.log 我还是得到了一些时髦的钻石。但是,当我在Firebug的网络选项卡下查看它时,一切都会显示良好:

    网络选项卡:

    {"error":false,
     "provinces":{"DZ-01":"Adrar",
                  "DZ-16":"Alger",
                  "DZ-23":"Annaba",
                  "DZ-44":"Aïn Defla",
                  "DZ-46":"Aïn Témouchent",
                  "DZ-05":"Batna",
                  "DZ-07":"Biskra",
                  "DZ-09":"Blida",
                  "DZ-34":"Bordj Bou Arréridj",
                  "DZ-10":"Bouira",
                  "DZ-35":"Boumerdès",
                  "DZ-08":"Béchar",
                  "DZ-06":"Béjaïa",
                  "DZ-02":"Chlef",
                  "DZ-25":"Constantine",
                  "DZ-17":"Djelfa",
                  "DZ-32":"El Bayadh",
                  "DZ-39":"El Oued",
                  "DZ-36":"El Tarf",
                  "DZ-47":"Ghardaïa",
                  "DZ-24":"Guelma",
                  "DZ-33":"Illizi",
                  "DZ-18":"Jijel",
                  "DZ-40":"Khenchela",
                  "DZ-03":"Laghouat",
                  "DZ-29":"Mascara",
                  "DZ-43":"Mila",
                  "DZ-27":"Mostaganem",
                  "DZ-28":"Msila",
                  "DZ-26":"Médéa",
                  "DZ-45":"Naama",
                  "DZ-31":"Oran",
                  "DZ-30":"Ouargla",
                  "DZ-04":"Oum el Bouaghi",
                  "DZ-48":"Relizane",
                  "DZ-20":"Saïda",
                  "DZ-22":"Sidi Bel Abbès",
                  "DZ-21":"Skikda",
                  "DZ-41":"Souk Ahras",
                  "DZ-19":"Sétif",
                  "DZ-11":"Tamanghasset",
                  "DZ-14":"Tiaret",
                  "DZ-37":"Tindouf",
                  "DZ-42":"Tipaza",
                  "DZ-38":"Tissemsilt",
                  "DZ-15":"Tizi Ouzou",
                  "DZ-13":"Tlemcen",
                  "DZ-12":"Tébessa"}}
    

    但当我这样做 console.log(text) 我从中得到的 阿贾克斯 ,我得到以下信息:

    {"error":false,
     "provinces":{"DZ-01":"Adrar",
                  "DZ-16":"Alger",
                  "DZ-23":"Annaba",
                  "DZ-44":"A�n Defla",
                  "DZ-46":"A�n T�mouchent",
                  "DZ-05":"Batna",
                  "DZ-07":"Biskra",
                  "DZ-09":"Blida",
                  "DZ-34":"Bordj Bou Arr�ridj",
                  "DZ-10":"Bouira",
                  "DZ-35":"Boumerd�s",
                  "DZ-08":"B�char",
                  "DZ-06":"B�ja�a",
                  "DZ-02":"Chlef",
                  "DZ-25":"Constantine",
                  "DZ-17":"Djelfa",
                  "DZ-32":"El Bayadh",
                  "DZ-39":"El Oued",
                  "DZ-36":"El Tarf",
                  "DZ-47":"Gharda�a",
                  "DZ-24":"Guelma",
                  "DZ-33":"Illizi",
                  "DZ-18":"Jijel",
                  "DZ-40":"Khenchela",
                  "DZ-03":"Laghouat",
                  "DZ-29":"Mascara",
                  "DZ-43":"Mila",
                  "DZ-27":"Mostaganem",
                  "DZ-28":"Msila",
                  "DZ-26":"M�d�a",
                  "DZ-45":"Naama",
                  "DZ-31":"Oran",
                  "DZ-30":"Ouargla",
                  "DZ-04":"Oum el Bouaghi",
                  "DZ-48":"Relizane",
                  "DZ-20":"Sa�da",
                  "DZ-22":"Sidi Bel Abb�s",
                  "DZ-21":"Skikda",
                  "DZ-41":"Souk Ahras",
                  "DZ-19":"S�tif",
                  "DZ-11":"Tamanghasset",
                  "DZ-14":"Tiaret",
                  "DZ-37":"Tindouf",
                  "DZ-42":"Tipaza",
                  "DZ-38":"Tissemsilt",
                  "DZ-15":"Tizi Ouzou",
                  "DZ-13":"Tlemcen",
                  "DZ-12":"T�bessa"}}
    

    在我看来,jquery对数据做了一些奇怪的事情。

    6 回复  |  直到 9 年前
        1
  •  16
  •   Vivin Paliath    14 年前

    我终于明白了。真奇怪!

    response.setCharacterEncoding(String) 工作(不知道是否与我的设置有关或是什么)。看起来它设置了字符编码,但出于某种原因jquery把它搞得一团糟。您可以这样显式地设置头:

    response.setHeader("Content-Type", "application/json; charset=ISO-8859-1");
    

    谢谢大家的帮助!

    编辑

    我做了一些研究并检查了 JavaDocs 看到这个:

    如果协议提供了这样做的方法,容器必须将servlet响应的编写器使用的字符编码传递给客户机。对于HTTP,字符编码作为文本媒体类型的内容类型头的一部分进行通信。 注意字符编码 不能 通过HTTP头进行通信 如果servlet未指定内容类型 ;但是,它仍然用于对通过servlet响应编写器编写的文本进行编码。 .

    因此,上述方法仍然有效,但您也可以(而且可能应该)这样做:

    response.setContentType("application/json");
    response.setCharacterEncoding("ISO-8859-1"); 
    
        2
  •  1
  •   Dave Jarvis James Eichele    14 年前

    你能用UTF-8吗?

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    

    在PHP中,可以将JSON数据编码为UTF-8:

    /**
     * Applies a UTF-8 encoding conversion for text.
     */
    function utf8_enc( $rows ) {
      $encoded = array();
    
      foreach( $rows as $row ) {
        $temp = array();
    
        foreach( $row as $name => $value ) {
          $temp[ $name ] = $value = mb_convert_encoding( $value, 'auto', 'UTF-8' );
        }
    
        array_push( $encoded, $temp );
      }
    
      return $encoded;
    }
    
    function db_json( $query ) {
      echo json_encode( utf8_enc( db_fetch_all( db_query( $query ) ) ) );
    }
    

    我在使用ISO-8859-1重音字符集时看到了一些奇怪的结果。我切换到了UTF-8,编码问题消失了。

    为了它的价值,我已经编码了 getJSON 如下:

      $.getJSON( HOST + 'cat.dhtml', function( data ) {
        var h = '';
        var len = data.length;
    
        for( var i = 0; i < len; i++ ) {
          h += '<option value="' + data[i].id + '">' + data[i].name + '</option>';
          categories[ data[i].id ] = data[i];
        }
    
        $('#category').html(h);
      });
    
        3
  •  1
  •   Oleg    14 年前

    在我看来,您收到了一个解析错误,因为响应数据被错误解码,因此包含了一些错误的字符。

    您可以尝试在jquery.ajax中插入一个附加参数

    dataFilter : function ( data, type ) {
        alert(data);
        return data;
    }
    

    如果你错了,但是 不同的 对于所有非ASCII字符(“_”、“_”等),您可以尝试将错误的编码字符替换为正确的字符,并从 dataFilter .

        4
  •  1
  •   mogsie    14 年前

    RFC 4627 声明JSON文本应以Unicode编码,无论这意味着什么,以及 json.org 指示所有字符都是“Unicode字符”:

    • 编码

      JSON文本应采用Unicode编码。默认编码是 UTF-8。

      因为JSON文本的前两个字符始终是ASCII 字符[rfc0020],可以确定八位字节 流是utf-8、utf-16(be或le)或utf-32(be或le)。 在前四个八位字节的空模式下。

         00 00 00 xx  UTF-32BE
         00 xx 00 xx  UTF-16BE
         xx 00 00 00  UTF-32LE
         xx 00 xx 00  UTF-16LE
         xx xx xx xx  UTF-8
      

    因此,如果您正在传输JSON并说它是ISO-8859-1,那么不同的JSON库可能会解释来自RFC的shall子句,该子句以各种方式定义JSON,例如通过编码替换字符或嗅探编码。最好的办法是,如果明显地把它带到你无法控制的地方,并告诉他们修复它:—)

    权变措施

    解决这个问题的一种方法是创建一个servlet过滤器,删除所有与utf-8和iso-8859-1不兼容的字符,并用json转义符替换它们:

    在以下片段中,将“_”替换为“u00e9”,以便安全地以相同的7位传输任何有问题的ISO-8859-1字符:

    之前: { "a" : "éte" }

    后: { "a" : "\u00E9te" }

    它没有那么清晰,但从语义上讲,它是相同的,任何一个好的JSON库都应该对它们进行相同的处理。

        5
  •  0
  •   phixr    14 年前

    PHP函数json_encode不支持ISO-8859-1编码数据。

    本文可能会帮助您解决问题: http://www.pabloviquez.com/2009/07/json-iso-8859-1-and-utf-8-%E2%80%93-part2/

        6
  •  0
  •   Jamal Azizbeigi    9 年前

    如果您想要从数据库中检索数据,那么应该在从Ajax页面发送请求的页面中的句子下编写这些数据。例如,如果在页面“A”中编写HTML和Ajax代码,并将变量从Java代码发送到页面“B”,则在页“B”中写入这些代码。
    别忘了数据库应该是Unicode模式,比如“utf8-general-ci”。

    mysqli_query ($conn,"set character_set_client='utf8'");
    mysqli_query ($conn,"set character_set_results='utf8'");
    mysqli_query ($conn,"set collation_connection='utf8_general_ci'");
    mysqli_query($conn,"set collation_connection='utf8_persian_ci'");
    mysqli_set_charset($conn,"set character_set_results='utf8'") ;
    mysqli_set_charset($conn,"set collation_connection='utf8_general_ci'") ;
    

    ; 我用波斯语写了这句话,你可以修改一下。 $conn 是用于连接到MySQL数据库中指定表的变量。