8

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

当我自己点击 servlet 时,我可以看到已输出的 JSON 数据。字符编码正确,没有一个字符看起来很奇怪。

但是,当我通过 AJAX 调用 servlet 并使用检索到的数据来填充选择框时,我得到 � 代替(似乎)所有有重音的字符(例如,带有重音或重音、分词或抑扬符的 i )。当我查看 Firebug 下 Net 选项卡中的响应时,我可以看到文本看起来不错。但是,当我使用该数据填充选择框时,我得到了带问号的菱形。

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

编辑

更多信息。我使用GETinjQuery.ajax并设置scriptCharsetISO-8859-1. 在服务器端,我已经明确地将编码设置为 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 的评论,我尝试查看是否可以将数据作为文本获取(因此设置dataTypetextin jQuery.ajax),然后我自己将其评估为 JSON(在 Javascript 中)。这似乎也不起作用!当我这样做时console.log,我仍然会得到时髦的钻石。但是,当我在 Firebug 的 Net 选项卡下查看它时,一切正常:

网络选项卡:

{"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)使用从中得到的东西时jQuery.ajax,我得到以下信息:

{"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 对数据做了一些奇怪的事情。

4

6 回答 6

17

我终于弄明白了。这很奇怪!

response.setCharacterEncoding(String)不起作用(知道它是否与我的设置有关或什么)。看起来它设置了字符编码,但由于某种原因,jQuery 把它搞砸了。您已像这样显式设置标题:

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

谢谢各位的帮助!

编辑

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

如果协议提供了这样做的方法,容器必须将用于 servlet 响应的编写器的字符编码传达给客户端。在 HTTP 的情况下,字符编码作为文本媒体类型的 Content-Type 标头的一部分进行通信。请注意,如果 servlet 未指定内容类型,则字符编码无法通过 HTTP 标头进行通信;但是,它仍然用于对通过 servlet 响应的 writer 编写的文本进行编码

所以上面仍然有效,但你也可以(并且可能应该)这样做:

response.setContentType("application/json");
response.setCharacterEncoding("ISO-8859-1"); 
于 2010-07-07T22:05:07.870 回答
2

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

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

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

如果所有非 ASCII 字符('ï'、'é' 等)都有错误但不同的字符,则可以尝试将错误的编码字符替换为正确的字符,并从dataFilter.

于 2010-07-07T22:25:33.890 回答
2

您可以改用 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);
  });
于 2010-07-07T20:43:23.603 回答
1

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 库可能会以各种方式解释定义 JSON 的 RFC 中的 SHALL 子句,例如通过编码替换字符或通过嗅探编码。最好的方法显然是把它带到你无法控制的地方并告诉他们修复它:-)

解决方法

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

在以下片段中,将 'é' 替换为 '\u00E9' 以便任何有问题的 ISO-8859-1 字符以相同的 7 位安全传输:

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

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

它不那么清晰,但从语义上讲,它是相同的,任何好的 JSON 库都应该对它们一视同仁。

于 2010-07-07T21:13:55.157 回答
0

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

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

于 2010-07-07T20:50:17.713 回答
0

如果您想从数据库中检索数据,您应该将这些写在从 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 数据库中指定表的变量。

于 2015-12-21T21:07:42.400 回答