Saltar al contenido

¿Cómo convierto caracteres UTF-8 especiales a su equivalente iso-8859-1 usando javascript?

Después de de una extensa búsqueda de información hemos podido resolver este conflicto que suelen tener ciertos lectores. Te dejamos la respuesta y nuestro objetivo es resultarte de mucha ayuda.

Solución:

En realidad, todo se almacena típicamente como Unicode de algún tipo internamente, pero no entremos en eso. Supongo que está obteniendo las icónicas cadenas de tipo “åäö” porque está usando un ISO-8859 como codificación de caracteres. Hay un truco que puedes hacer para convertir esos caracteres. Él escape y unescape Las funciones utilizadas para codificar y decodificar cadenas de consulta están definidas para caracteres ISO, mientras que las más nuevas encodeURIComponent y decodeURIComponent que hacen lo mismo, están definidos para caracteres UTF8.

escape codifica caracteres ISO-8859-1 extendidos (puntos de código UTF U+0080-U+00ff) como %xx (hexadecimal de dos dígitos), mientras que codifica puntos de código UTF U+0100 y superiores como %uxxxx (%u seguido de cuatro dígitos hexadecimales). Por ejemplo, escape("å") == "%E5" y escape("あ") == "%u3042".

encodeURIComponent codifica por ciento los caracteres extendidos como una secuencia de bytes UTF8. Por ejemplo, encodeURIComponent("å") == "%C3%A5" y encodeURIComponent("あ") == "%E3%81%82".

Entonces puedes hacer:

fixedstring = decodeURIComponent(escape(utfstring));

Por ejemplo, un carácter codificado incorrectamente “å” se convierte en “Ã¥”. El comando hace escape("Ã¥") == "%C3%A5" que son los dos caracteres ISO incorrectos codificados como bytes individuales. Entonces decodeURIComponent("%C3%A5") == "å"donde los bytes codificados en dos por ciento se interpretan como una secuencia UTF8.

Si necesita hacer lo contrario por alguna razón, eso también funciona:

utfstring = unescape(encodeURIComponent(originalstring));

¿Hay alguna manera de diferenciar entre cadenas UTF8 malas y cadenas ISO? Resulta que hay. La función decodeURIComponent utilizada anteriormente generará un error si se le proporciona una secuencia codificada con formato incorrecto. Podemos usar esto para detectar con una gran probabilidad si nuestro string es UTF8 o 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 assume that we have an ISO string.
    fixedstring=badstring;

El problema es que una vez que se muestra la página, el contenido estará en la codificación descrita en la metaetiqueta de tipo de contenido. El contenido en codificación “incorrecta” ya está distorsionado.

Lo mejor es hacer esto en el servidor antes de publicar la página. O como he sabido decir: UTF-8 de extremo a extremo o morir.

Dado que la pregunta sobre cómo convertir de ISO-8859-1 a UTF-8 está cerrada debido a esto, voy a publicar mi solución aquí.

El problema es cuando intenta OBTENER algo usando XMLHttpRequest, si XMLHttpRequest.responseType es “texto” o está vacío, XMLHttpRequest.response se transforma en DOMString y ahí es donde las cosas se rompen. Después, es casi imposible trabajar de manera confiable con eso string.

Ahora, si el contenido del servidor es ISO-8859-1, deberá forzar que la respuesta sea del tipo “Blob” y luego convertirla a DOMSTring. Por ejemplo:

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's no further conversion required
           Promise.resolve(reader.result);
        );
        reader.readAsBinaryString(ajax.response);
    

Parece que la magia está sucediendo en readAsBinaryString así que tal vez alguien pueda arrojar algo de luz sobre por qué esto funciona.

valoraciones y reseñas

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *