Подтвердить что ты не робот

Как преобразовать специальные символы UTF-8 в их эквивалент iso-8859-1 с помощью javascript?

Я делаю приложение javascript, которое извлекает файлы .json с jquery и вводит данные на веб-страницу, в которую она встроена.

Файлы .json кодируются с помощью UTF-8 и содержат акцентированные символы, такие как é, ö и å.

Проблема в том, что я не контролирую кодировку на страницах, которые будут использовать приложение.

Некоторые будут использовать UTF-8, но другие будут использовать кодировку iso-8859-1. Это, конечно же, украсит специальные символы из файлов .json.

Как преобразовать специальные символы UTF-8 в их эквивалент iso-8859-1 с помощью javascript?

4b9b3361

Ответ 1

Собственно, все обычно хранится как Unicode в некотором роде внутри, но позволяет не вдаваться в это. Я предполагаю, что вы получаете знаковые строки типа "à ¥ äö", потому что вы используете ISO-8859 в качестве кодировки символов. Там есть трюк, который вы можете сделать, чтобы преобразовать эти символы. Функции escape и unescape, используемые для кодирования и декодирования строк запроса, определены для символов ISO, тогда как более новые encodeURIComponent и decodeURIComponent, которые делают то же самое, определены для символов UTF8.

escape кодирует расширенные символы ISO-8859-1 (UTF-коды U + 0080-U + 00ff) как %xx (двузначный шестнадцатеричный), тогда как он кодирует UTF-коды U + 0100 и выше как %uxxxx (%u, а затем четырехзначный шестнадцатеричный). Например, escape("å") == "%E5" и escape("あ") == "%u3042".

encodeURIComponent percent - кодирует расширенные символы как последовательность байтов UTF8. Например, encodeURIComponent("å") == "%C3%A5" и encodeURIComponent("あ") == "%E3%81%82".

Итак, вы можете сделать:

fixedstring = decodeURIComponent(escape(utfstring));

Например, неправильно закодированный символ "å" становится "Ã ¥". Команда escape("Ã¥") == "%C3%A5", которая является двумя неправильными символами ISO, закодированными как одиночные байты. Затем decodeURIComponent("%C3%A5") == "å", где два процента кодированных байтов интерпретируются как последовательность UTF8.

Если вам по какой-то причине нужно сделать обратное, это тоже работает:

utfstring = unescape(encodeURIComponent(originalstring));

Есть ли способ разграничения между строками плохого UTF8 и строками ISO? Оказывается, есть. Функция decodeURIComponent, используемая выше, выдает ошибку, если задана некорректная закодированная последовательность. Мы можем использовать это, чтобы с большой вероятностью обнаружить, является ли наша строка UTF8 или ISO.

var fixedstring;

try{
    // If the string is UTF-8, this will work and not throw an error.
    fixedstring=decodeURIComponent(escape(badstring));
}catch(e){
    // If it isn't, an error will be thrown, and we can asume that we have an ISO string.
    fixedstring=badstring;
}

Ответ 2

Проблема заключается в том, что после того, как страница будет подана, содержимое будет находиться в кодировке, описанной в метатеге контента. Содержимое в "неправильной" кодировке уже искажено.

Лучше всего сделать это на сервере, прежде чем обслуживать страницу. Или, как я знаю, можно сказать: UTF-8 от конца до конца или умереть.

Ответ 3

Внутренне, строки Javascript - все Unicode (фактически UCS-2, подмножество UTF-16).

Если вы извлекаете файлы JSON отдельно через AJAX, вам нужно только убедиться, что файлы JSON обслуживаются с правильным типом контента и кодировкой: Content-Type: application/json; charset="utf-8"). Если вы это сделаете, jQuery должен был уже правильно их интерпретировать к моменту доступа к десериализованным объектам.

Не могли бы вы привести пример кода, который вы используете для извлечения объектов JSON?

Ответ 4

Поскольку question о том, как конвертировать из ISO-8859-1 в UTF-8, закрыт из-за этого, я собираюсь опубликовать свое решение здесь.

Проблема заключается в том, что вы пытаетесь ПОЛУЧИТЬ что-либо, используя XMLHttpRequest, если XMLHttpRequest.responseType является "текстовым" или пустым, XMLHttpRequest.response преобразуется в DOMString, и это расстраивается. После этого почти невозможно надежно работать с этой строкой.

Теперь, если содержимое с сервера соответствует ISO-8859-1, вам придется заставить ответ иметь тип " Blob", а затем преобразовать его в DOMSTring. Например:

var ajax = new XMLHttpRequest();
ajax.open('GET', url, true);
ajax.responseType = 'blob';
ajax.onreadystatechange = function(){
    ...
    if(ajax.responseType === 'blob'){
        // Convert the blob to a string
        var reader = new window.FileReader();
        reader.addEventListener('loadend', function() {
           // For ISO-8859-1 there no further conversion required
           Promise.resolve(reader.result);
        });
        reader.readAsBinaryString(ajax.response);
    }
}

Кажется, что магия происходит на readAsBinaryString, поэтому, возможно, кто-то может пролить свет на то, почему это работает.

Ответ 5

Я искал этот ответ, но думаю, что в одной строке против многих кода может быть что-то вроде этого:

   var converted = "<?php echo mb_convert_encoding($str_to_convert, 'UTF-8', 'ISO-8859-1'); ?>";

Это сработало для меня, но если вы поместите var в php, вот так:

   document.write("<?php $str_to_convert = " + your_str + " ?>");

Надеюсь, это также поможет любому.

Ответ 6

вы должны добавить эту строку над своей страницей

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