我有一个输出JSON的servlet。 servlet的输出编码是ISO-8859-1。我们的webapp中的页面也设置为ISO-8859-1。我会使用UTF-8,但这不在我的控制之内;我们必须使用ISO-8859-1。
当我单独点击servlet时,我可以看到已经输出的JSON数据。字符编码是正确的,没有一个字符看起来很奇怪。
然而,当我通过AJAX调用servlet并使用检索到的数据来填充选择框时,我得到了it代替所有带有重音符号的字符(例如我有严重或尖锐的重音,dieresis ,或抑扬)。当我在Firebug下的Net选项卡中查看响应时,我可以看到文本看起来很好。但是,当我使用该数据填充选择框时,我会得到带有问号的钻石。
这些字符都是有效的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
设置为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正在做一些奇怪的数据。
答案 0 :(得分:17)
我终于明白了。这很奇怪!
response.setCharacterEncoding(String)
不工作(不知道它是否与我的设置有关或什么)。看起来它设置了字符编码,但由于某种原因,jQuery混淆了它。您可以像这样显式设置标题:
response.setHeader("Content-Type", "application/json; charset=ISO-8859-1");
感谢大家的帮助!
修改强>
我做了一些研究并检查了JavaDocs并看到了这个:
如果协议提供了一种方法,容器必须将用于servlet响应编写器的字符编码传递给客户端。在HTTP的情况下,字符编码作为文本媒体类型的Content-Type标题的一部分进行通信。 请注意,如果servlet未指定内容类型,则字符编码不能通过HTTP标头进行通信;但是,它仍然用于编码通过servlet响应的编写器编写的文本。
所以上面的内容仍然有效,但您也可以(也可能应该)这样做:
response.setContentType("application/json");
response.setCharacterEncoding("ISO-8859-1");
答案 1 :(得分:1)
您可以使用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);
});
答案 2 :(得分:1)
RFC 4627声明JSON文本应该用Unicode编码,无论这意味着什么,json.org表示所有字符都是“unicode characters”:
编码
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',以便任何有问题的ISO-8859-1字符以相同的7位安全传输:
之前:{ "a" : "éte" }
之后:{ "a" : "\u00E9te" }
它不那么清晰,但从语义上讲,它是相同的,任何好的JSON库都应该对它们进行相同的处理。
答案 3 :(得分:1)
在我看来,您收到解析错误,因为响应数据被错误解码,因此包含一些错误的字符。
你可以尝试在jQuery.ajax中插入一个额外的参数
dataFilter : function ( data, type ) {
alert(data);
return data;
}
如果所有非ASCII字符('ï','é'等)都有错误但不同的字符,您可以尝试将错误的编码字符替换为正确的字符和从dataFilter
返回正确的编码数据。
答案 4 :(得分:0)
php函数json_encode不支持ISO-8859-1编码数据。
本文可能会帮助您解决问题:http://www.pabloviquez.com/2009/07/json-iso-8859-1-and-utf-8-%E2%80%93-part2/
答案 5 :(得分: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数据库中指定表的变量。