Как преобразовать специальные символы UTF-8 в их эквивалент iso-8859-1 с помощью javascript?
Я делаю приложение javascript, которое извлекает файлы .json с jquery и вводит данные на веб-страницу, в которую она встроена.
Файлы .json кодируются с помощью UTF-8 и содержат акцентированные символы, такие как é, ö и å.
Проблема в том, что я не контролирую кодировку на страницах, которые будут использовать приложение.
Некоторые будут использовать UTF-8, но другие будут использовать кодировку iso-8859-1. Это, конечно же, украсит специальные символы из файлов .json.
Как преобразовать специальные символы UTF-8 в их эквивалент iso-8859-1 с помощью javascript?
Ответы
Ответ 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" />