вызов jQuery AJAX портит кодировку символов
у меня есть сервлет, который выводит JSON. Выходная кодировка сервлета-ISO-8859-1. Страницы в нашем веб-приложении также установлены на ISO-8859-1. Я бы использовал UTF-8, но это вне моего контроля; мы должны использовать ISO-8859-1.
когда я нажимаю сервлет сам по себе, я вижу данные JSON, которые были выведены. Кодировка символов правильная, и ни один из символов не выглядит странно.
однако, когда я вызываю сервлет через AJAX и использую данные, полученные для заполняя поле выбора, я получаю � вместо (кажется) всех символов, которые имеют акценты (например, I с серьезным или острым акцентом, диерезисом или окружностью). Когда я смотрю на ответ на вкладке Net под Firebug, я вижу, что текст выглядит нормально. Однако, когда я использую эти данные для заполнения поля выбора, я получаю алмаз с вопросительным знаком.
эти символы являются действительными символами ISO-8859-1, и поэтому я не понимаю, почему они не появляются правильно.
редактировать
дополнительная информация. Я использую GET
на jQuery.ajax
и я scriptCharset
to ISO-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) {
...
},
});
мой сервлет использует org.json.JSONObject
и просто выводит строку, делая response.getWriter().print(jsonObject.toString());
обновление
в комментариях о JSON и как это должно быть UTF-8, я попытался увидеть, могу ли я захватить данные как текст (так что установите dataType
to text
на jQuery.ajax
), а затем оценить его как JSON себя (в Javascript). Это тоже не работает! Когда я делаю console.log
, я все еще получаю фанки алмазов. Однако, когда я смотрю на него под вкладкой Net в Firebug, все выглядит нормально:
Net tab:
{"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 делает что-то странное с данными.
6 ответов
я, наконец, понял. Это довольно странно!
response.setCharacterEncoding(String)
тут не работа (не знаю, связано ли это с моей настройкой или что). Похоже, он устанавливает кодировку символов, но по какой-то причине jQuery все портит. У вас есть явно установить заголовки так:
response.setHeader("Content-Type", "application/json; charset=ISO-8859-1");
Спасибо за помощь, всем!
редактировать
Я сделал некоторые исследования и проверили JavaDocs и увидел это:
контейнеры должны передавать кодировку символов, используемую для записи ответа сервлета клиенту, если протокол предоставляет способ сделать это. В случае HTTP кодировка символов передается как часть заголовка Content-Type для типов текстовых носителей. обратите внимание, что кодировка символов не может передаваться через HTTP-заголовки если сервлет не указывает тип контента; однако он все еще используется для кодирования текст, написанный через writer ответа сервлета.
Так выше все еще работает, но вы также можете (и вероятно должны) сделать это:
response.setContentType("application/json");
response.setCharacterEncoding("ISO-8859-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);
});
мне кажется, вы получаете ошибку разбора, потому что данные ответа неправильно декодированы и поэтому содержат неправильные символы.
вы можете попробовать вставить в jQuery.ajax дополнительный параметр
dataFilter : function ( data, type ) {
alert(data);
return data;
}
Если вы ошибаетесь, но разные символы для всех символов, отличных от ASCII ("ï", " é " и т. д.), Вы можете попытаться заменить неправильные закодированные символы на правильные символы и вернуть правильные закодированные данные из dataFilter
.
RFC 4627 заявляет, что текст JSON должен быть закодирован в Unicode, что бы это ни значило, и json.org указывает, что все символы являются "символами Юникода":
-
кодирование
текст JSON должен быть закодирован в Юникоде. Кодировку по умолчанию 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 могут интерпретировать предложение SHALL из RFC, которое определяет JSON различными способами, например, кодируя символ замены или нюхая кодировку. Лучший способ, если очевидно, чтобы принять это к тому, что находится вне вашего контроля и сказать им, чтобы исправить это :-)
решения
один из способов обойти это-создать фильтр сервлетов, который удаляет все символы, несовместимые с UTF-8 и ISO-8859-1, и заменяет их на JSON escapes:
в следующем фрагменте замените " é " на "\u00E9", чтобы любой оскорбительный символ ISO-8859-1 безопасно транспортировался в 7-битах, которые идентичны:
перед: { "a" : "éte" }
после: { "a" : "\u00E9te" }
Это не так разборчиво, но семантически говоря, это то же самое, и любая хорошая библиотека JSON должна относиться к ним одинаково.
функция php json_encode не поддерживает кодированные данные ISO-8859-1.
эта статья может помочь вам с вашей проблемой: http://www.pabloviquez.com/2009/07/json-iso-8859-1-and-utf-8-%E2%80%93-part2/
Если вы хотите получить данные из базы данных, вы должны написать их под предложениями на странице, которая отправляет запрос со страницы ajax. Например, если вы пишете код HTML и AJAX на странице " A "и отправляете переменную из кода 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.