вызов Ajax jQuery портит кодировку символов

У меня есть сервлет, это производит JSON. Выходное кодирование для сервлета является ISO-8859-1. Страницы в нашем веб-приложении также установлены на ISO-8859-1. Я использовал бы UTF-8, но это вне моего управления; мы должны использовать ISO-8859-1.

Когда я поразил сервлет отдельно, я вижу данные JSON, которые были произведены. Кодировка символов корректна, и ни один из символов не выглядит странным.

Однако, когда я называю сервлет через Ajax и использую полученные данные для заполнения избранного поля, я получаю � вместо (это кажется), все символы, которые имеют диакритические знаки (например, я с серьезным или акутом, диерезисом или циркумфлексом). Когда я смотрю на ответ на вкладке Net под Firebug, я вижу, что это текст выглядит хорошо. Однако, когда я использую те данные для заполнения избранного поля, я получаю ромб с вопросительным знаком.

Эти символы являются всеми допустимыми символами ISO-8859-1, и таким образом, я не понимаю, почему они не обнаруживаются правильно.

Править

Еще некоторая информация. Я использую GET в jQuery.ajax и я установил scriptCharset кому: 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 кому: text в jQuery.ajax) и затем оцените его как JSON самостоятельно (в JavaScript). Это, кажется, не работает также! Когда я делаю console.log, Я все еще получаю броские ромбы. Однако, когда я смотрю на него под вкладкой Net в 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) с тем, от чего я добираюсь 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 делает что-то странное с данными.

7
задан Vivin Paliath 7 July 2010 в 21:47
поделиться

5 ответов

Я наконец-то разобрался. Это довольно странно!

response.setCharacterEncoding(String) работает не работает (не знаю, связано ли это с моей настройкой или нет). Похоже, что он устанавливает кодировку символов, но по какой-то причине jQuery все путает. Вы должны явно установить заголовки так:

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

Спасибо всем за помощь!

EDIT

Я провел небольшое исследование и проверил JavaDocs и увидел следующее:

Контейнеры должны сообщать кодировку символов, используемую для записи ответа сервлета, клиенту, если протокол предоставляет для этого возможность. В случае HTTP кодировка символов передается как часть заголовка Content-Type для текстовых типов медиа. Обратите внимание, что кодировка символов не может передаваться через HTTP-заголовки если сервлет не указывает тип содержимого ; однако она все равно используется для кодирования текста, написанного с помощью писателя ответа сервлета .

Так что вышеописанное все еще работает, но вы также можете (и, вероятно, должны) сделать следующее:

response.setContentType("application/json");
response.setCharacterEncoding("ISO-8859-1"); 
17
ответ дан 6 December 2019 в 09:18
поделиться

Можете ли вы использовать вместо этого 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);
  });
1
ответ дан 6 December 2019 в 09:18
поделиться

Мне кажется, что вы получаете ошибку синтаксического анализа, потому что данные ответа неправильно декодированы и поэтому содержат некоторые неправильные символы.

Вы можете попытаться вставить в jQuery.ajax дополнительный параметр

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

Если у вас будут неправильные, но разные символы для всех символов, отличных от ASCII ('ï', 'é' и т. Д.), Вы можете попытаться заменить неправильные закодированные символы на правильные символы и вернуть правильные закодированные данные из dataFilter.

1
ответ дан 6 December 2019 в 09:18
поделиться

RFC 4627 утверждает, что текст JSON ДОЛЖЕН быть закодирован в Юникоде, что бы это ни значило, и 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 х 00 х 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:

В следующем фрагменте замените 'é' на '\u00E9', чтобы любой некоррегулированный символ ISO-8859-1 был безопасно транспортирован в идентичных 7-битах:

До: { "a" : "éte" }

После: { "a" : "\u00E9te" }

Это не так разборчиво, но с точки зрения семантически это одно и то же, и любая хорошая библиотека JSON должна относиться к ним одинаково.

1
ответ дан 6 December 2019 в 09:18
поделиться

Функция php json_encode не поддерживает данные в кодировке ISO-8859-1.

Эта статья может помочь вам в решении вашей проблемы: http://www.pabloviquez.com/2009/07/json-iso-8859-1-and-utf-8-%E2%80%93- часть2 /

0
ответ дан 6 December 2019 в 09:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: