使用 Javascript 解码 UTF-8

IT技术 javascript unicode utf8-decode xhtml-transitional
2021-01-30 07:33:11

我在传递 UTF-8 编码字符串的 XHTML 网页中有 Javascript。它需要继续传递 UTF-8 版本,并对其进行解码。如何解码 UTF-8 字符串以进行显示?

<script type="text/javascript">
// <![CDATA[
function updateUser(usernameSent){
    var usernameReceived = usernameSent; // Current value: Größe
    var usernameDecoded = usernameReceived;  // Decode to: Größe
    var html2id = '';
    html2id += 'Encoded: ' + usernameReceived + '<br />Decoded: ' + usernameDecoded;
    document.getElementById('userId').innerHTML = html2id;
}
// ]]>
</script>
6个回答

回答最初的问题:这是在 javascript 中解码 utf-8 的方法:

http://ecmanaut.blogspot.ca/2006/07/encoding-decoding-utf8-in-javascript.html

具体来说,

function encode_utf8(s) {
  return unescape(encodeURIComponent(s));
}

function decode_utf8(s) {
  return decodeURIComponent(escape(s));
}

我们已经在我们的生产代码中使用它 6 年了,它运行完美。

但是请注意,不推荐使用 escape() 和 unescape()。 看到这个。

这是我的代码:s = decodeURIComponent(escape(s)); 请注意,您必须将其放在 try/catch 块中。
2021-03-24 07:33:11
我试过使用decodeURIComponent(escape(usernameReceived))and decodeURIComponent(usernameReceived),但都没有转换usernameReceived你能展示一些功能代码吗?
2021-03-30 07:33:11
如果答案回答了问题,请考虑将答案标记为已接受,或者如果您仍有问题,请告诉我。
2021-04-02 07:33:11
这对我有用。但是,如您所知,不推荐使用转义方法 ID。我们使用的是 TypeScript,默认情况下它不存在。那么逃生的最佳选择是什么。在这种情况下, encodeURI 和 encodeURIComponent 无法替换转义她,因为它们会产生不同的输出。
2021-04-07 07:33:11
当已弃用的功能实际上很有用时,防止它被删除的最佳方法是继续使用它而不是避免使用它。浏览器供应商使用使用统计来确定何时删除功能。
2021-04-11 07:33:11

这应该有效:

// http://www.onicos.com/staff/iz/amuse/javascript/expert/utf.txt

/* utf.js - UTF-8 <=> UTF-16 convertion
 *
 * Copyright (C) 1999 Masanao Izumo <iz@onicos.co.jp>
 * Version: 1.0
 * LastModified: Dec 25 1999
 * This library is free.  You can redistribute it and/or modify it.
 */

function Utf8ArrayToStr(array) {
    var out, i, len, c;
    var char2, char3;

    out = "";
    len = array.length;
    i = 0;
    while(i < len) {
    c = array[i++];
    switch(c >> 4)
    { 
      case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
        // 0xxxxxxx
        out += String.fromCharCode(c);
        break;
      case 12: case 13:
        // 110x xxxx   10xx xxxx
        char2 = array[i++];
        out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));
        break;
      case 14:
        // 1110 xxxx  10xx xxxx  10xx xxxx
        char2 = array[i++];
        char3 = array[i++];
        out += String.fromCharCode(((c & 0x0F) << 12) |
                       ((char2 & 0x3F) << 6) |
                       ((char3 & 0x3F) << 0));
        break;
    }
    }

    return out;
}

查看JSFiddle 演示

另请参阅相关问题:此处此处

赞成真正了解解码 UTF-8 是什么。
2021-03-16 07:33:11
此代码不正确。fromCharCode接受 UTF-16 值,因此您需要在调用它之前转换为 UTF-16。
2021-03-26 07:33:11

也许使用textDecoder就足够了。

虽然在 IE 中不受支持。

var decoder = new TextDecoder('utf-8'),
    decodedMessage;

decodedMessage = decoder.decode(message.data);

处理非 UTF8 文本

在这个例子中,我们解码俄语文本“Привет, мир!”,意思是“Hello, world”。在我们的 TextDecoder() 构造函数中,我们指定适用于西里尔文脚本的 Windows-1251 字符编码。

    let win1251decoder = new TextDecoder('windows-1251');
    let bytes = new Uint8Array([207, 240, 232, 226, 229, 242, 44, 32, 236, 232, 240, 33]);
    console.log(win1251decoder.decode(bytes)); // Привет, мир!

此处描述了 TextDecoder 的接口

从字符串中检索字节数组同样简单:

const decoder = new TextDecoder();
const encoder = new TextEncoder();

const byteArray = encoder.encode('Größe');
// converted it to a byte array

// now we can decode it back to a string if desired
console.log(decoder.decode(byteArray));

如果您使用不同的编码,则必须在编码时对其进行补偿。TextEncoder 的构造函数中的参数是此处列出的任何一种有效编码

我从哪里得到 message.data?
2021-03-20 07:33:11
@JamieHutber 也许您正在寻找这个?:developer.mozilla.org/en-US/docs/Web/API/TextDecoder
2021-03-21 07:33:11
这只是在现有的混乱中再增加一层混乱。还有一个实验性的
2021-03-28 07:33:11
@ÁlvaroGonzález 但它可以工作并且可能是标准的(未来的浏览器也需要支持这一点,好吗?)
2021-03-30 07:33:11
现在这不是实验性的,在所有现代浏览器中都有很好的支持,绝对是每个人的正确选择(除非你仍然必须支持 IE)
2021-04-12 07:33:11

这是一个处理所有 Unicode 代码点的解决方案,包括大写(4 字节)值,并受所有现代浏览器(IE 和其他浏览器 > 5.5)支持。它使用 decodeURIComponent(),但不使用已弃用的转义/取消转义函数:

function utf8_to_str(a) {
    for(var i=0, s=''; i<a.length; i++) {
        var h = a[i].toString(16)
        if(h.length < 2) h = '0' + h
        s += '%' + h
    }
    return decodeURIComponent(s)
}

已在GitHub 上测试并可用

要从字符串创建 UTF-8:

function utf8_from_str(s) {
    for(var i=0, enc = encodeURIComponent(s), a = []; i < enc.length;) {
        if(enc[i] === '%') {
            a.push(parseInt(enc.substr(i+1, 2), 16))
            i += 3
        } else {
            a.push(enc.charCodeAt(i++))
        }
    }
    return a
}

已在GitHub 上测试并可用

希望详细说明参数和结果。Unicode 使我非常困惑。
2021-03-29 07:33:11

更新@Albert 的答案,为表情符号添加条件。

function Utf8ArrayToStr(array) {
    var out, i, len, c;
    var char2, char3, char4;

    out = "";
    len = array.length;
    i = 0;
    while(i < len) {
    c = array[i++];
    switch(c >> 4)
    { 
      case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
        // 0xxxxxxx
        out += String.fromCharCode(c);
        break;
      case 12: case 13:
        // 110x xxxx   10xx xxxx
        char2 = array[i++];
        out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));
        break;
      case 14:
        // 1110 xxxx  10xx xxxx  10xx xxxx
        char2 = array[i++];
        char3 = array[i++];
        out += String.fromCharCode(((c & 0x0F) << 12) |
                       ((char2 & 0x3F) << 6) |
                       ((char3 & 0x3F) << 0));
        break;
     case 15:
        // 1111 0xxx 10xx xxxx 10xx xxxx 10xx xxxx
        char2 = array[i++];
        char3 = array[i++];
        char4 = array[i++];
        out += String.fromCodePoint(((c & 0x07) << 18) | ((char2 & 0x3F) << 12) | ((char3 & 0x3F) << 6) | (char4 & 0x3F));

        break;
    }

    return out;
}
注意:这适用于格式良好的 UTF-8 输入,但在某些情况下会在没有通知的情况下中断:例如,它假设剩余的字节数正确,并且它们具有正确的继续序列0b10xxxxxx,并且在case 15其中应该只匹配0b11110xxx或它可以解码非法代码点。
2021-03-28 07:33:11