Декодировать UTF-8 с помощью Javascript

У меня есть Javascript на веб-странице XHTML, которая передает строки в кодировке UTF-8. Нужно продолжать передавать версию 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>

person Jarrett Mattson    schedule 13.11.2012    source источник
comment
Так в чем твоя проблема? привести пример.   -  person xiaoyi    schedule 13.11.2012
comment
Мне нужно расшифровать UTF-8; Größe следует расшифровывать от Größe.   -  person Jarrett Mattson    schedule 13.11.2012
comment
Что за Größe? Это не кодировка URL.   -  person xiaoyi    schedule 13.11.2012
comment
Это не та проблема, для решения которой вы используете JavaScript. Чтобы решить эту проблему, нужно добавить соответствующий тег meta, например <meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />, и XML-декларацию, например <?xml version="1.0" encoding="UTF-8"?>.   -  person icktoofay    schedule 13.11.2012
comment
И поместите мета как первый тег в разделе <head>. Отправьте спецификацию клиенту и выполните эту работу.   -  person xiaoyi    schedule 13.11.2012
comment
Мне также нужно, чтобы он был закодирован в том же скрипте.   -  person Jarrett Mattson    schedule 13.11.2012
comment
Что? Пока ваша веб-страница закодирована в UTF-8, js будет обрабатывать строки как закодированные в UTF-8, а encodeURIComponent() и decodeURIComponent() будут предполагать, что данные имеют кодировку UTF-8.   -  person xiaoyi    schedule 13.11.2012
comment
где и зачем лишняя декларация xml?   -  person Jarrett Mattson    schedule 13.11.2012
comment
Größe — это не UTF-8 (ну, может быть, но не по сути), это беспорядок. Он уже сломан. Несколько раз, кажется. Его не нужно расшифровывать, везде, где он дает сбой и ломается, нужно исправлять. Дайте больше контекстной информации, иначе трудно помочь.   -  person deceze♦    schedule 13.11.2012
comment
Вот как PHP закодировал его, по-видимому, кажется, что он отлично его декодирует. Он знает, что с ним делать после этого, просто не может правильно отобразить текст.   -  person Jarrett Mattson    schedule 13.11.2012
comment
Похоже, что GröÃe на веб-странице не расшифровано.   -  person Jarrett Mattson    schedule 13.11.2012
comment
Откуда берутся ваши данные? и как вы доставили его клиенту? Настройка кодирования необходима для каждого шага. allseeing-i.com/How-to- настроить-ваш-PHP-сайт для использования-UTF8   -  person xiaoyi    schedule 13.11.2012
comment
Данные представляют собой имя файла UTF8_encode с помощью PHP. Он декодируется на этой странице, где он в конечном итоге передается обратно в PHP на той же странице (работает).   -  person Jarrett Mattson    schedule 13.11.2012
comment
Если данные закодированы в UTF8, нет необходимости декодировать их перед отправкой клиенту. Вы можете опубликовать все это в своем вопросе?   -  person xiaoyi    schedule 13.11.2012
comment
Не применяйте случайным образом utf8_encode. Тебе это нужно? Вы знаете, зачем вам это нужно?   -  person deceze♦    schedule 13.11.2012
comment
Если пользователь попытается использовать его, то да. Это не применяется случайным образом, а сделано так, чтобы имена файлов не ломались.   -  person Jarrett Mattson    schedule 13.11.2012
comment
Пользователь пытается использовать его, ссылаясь на UTF-8? Тогда вам не нужно utf8_encode. Не обязательно. utf8_encode преобразует кодировку строки из ISO 8859-1 в UTF-8. Он пытается сделать это, даже если строка уже имеет кодировку UTF-8. UTF-8 Größe → utf8_encode → GröÃe → utf8_encode Größe. Если вы применяете его, когда он вам не нужен, ваша струна испортится.   -  person deceze♦    schedule 13.11.2012
comment
Ах, я должен дважды кодировать и декодировать с PHP/XHTML для имени файла. Есть ли лучший способ сделать имя файла, например MD5? Что я все еще пытаюсь сделать, так это декодировать UTF-8 с помощью Javscript!   -  person Jarrett Mattson    schedule 14.11.2012
comment
Я голосую за то, чтобы закрыть этот вопрос, потому что он полностью вводит в заблуждение и только привлекает столь же вводящие в заблуждение ответы, которые только сеют путаницу.   -  person Álvaro González    schedule 17.11.2016
comment
Я согласен с предыдущими людьми в том, насколько эта ветка вводит в заблуждение, но на самом деле большинство людей ищут чистую библиотеку кодирования/декодирования javascript, которая решит их проблемы с кодировкой, так что это то, что я нашел, когда я искал в Google больше, чем просто Кодировка/декодирование UTF8 : github.com/inexorabletash/text-encoding, Это вставка из их README: Поддерживаются все кодировки из спецификации Encoding, наслаждайтесь!   -  person Olle Tiinus    schedule 26.02.2019


Ответы (14)


Чтобы ответить на исходный вопрос: вот как вы декодируете utf-8 в javascript:

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() устарели. Посмотрите это.

person CpnCrunch    schedule 03.12.2012
comment
Я пытался использовать decodeURIComponent(escape(usernameReceived)) и decodeURIComponent(usernameReceived), но ни один из них не преобразует usernameReceived. Можете ли вы показать какой-нибудь функциональный код? - person Jarrett Mattson; 30.01.2014
comment
Вот мой код: s = decodeURIComponent(escape(s)); Обратите внимание, что вы должны поместить его в блок try/catch. - person CpnCrunch; 31.01.2014
comment
Пожалуйста, рассмотрите возможность пометить ответ как принятый, если он отвечает на вопрос, или дайте мне знать, если у вас все еще есть проблемы с ним. - person CpnCrunch; 11.11.2015
comment
Это работает для меня. Но, как вы знаете, идентификатор метода escape устарел. Мы используем TypeScript, и его нет по умолчанию. Итак, что является лучшей альтернативой для побега. encodeURI и encodeURIComponent не работают, чтобы заменить escape her в этом сценарии, поскольку они производят разные выходные данные. - person Joy George Kunjikkuru; 10.12.2015
comment
Joymon: вам нужно будет заменить как escape(), так и unescape(). Хотя я сам не пробовал. - person CpnCrunch; 11.12.2015
comment
не работает плагин вкладки пользовательского интерфейса jquery ... необходимо <meta http-equiv="Content-Type" content="text/html;charset=utf-8"> для нормальной работы. Благодарность! - person KingRider; 18.09.2017
comment
Меня попросили добавить комментарий, потому что я проголосовал за это. Но все, что я могу сказать, это то, что, поскольку побег устарел, этот ответ неприемлем. Почему экранирование устарело, если оно выполняет важную функцию? И почему в JavaScript нет встроенной поддержки UTF-8? И почему это никого не волнует (последний комментарий был два года назад). - person David Spector; 05.09.2019
comment
Дэвид: да, ты прав. Я обновил ответ, чтобы отметить, что escape и unescape устарели. Замена на encodeURIComponent и decodeURIComponent не работает (неудивительно, поскольку вы будете вызывать ту же функцию кодирования/декодирования, что не даст никакого эффекта). Я думаю, маловероятно, что они будут удалены в ближайшее время, но если они будут удалены (или если вы хотите быть в безопасности), лучшим вариантом будет использование решения lauthu или fakedrake. - person CpnCrunch; 06.09.2019
comment
Когда устаревшая функциональность действительно полезна, лучший способ предотвратить ее удаление — продолжать использовать ее, а не воздерживаться от ее использования. Поставщики браузеров используют статистику использования, чтобы определить, когда следует удалить функцию. - person GetFree; 04.10.2019

Это должно работать:

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

/* utf.js - UTF-8 <=> UTF-16 convertion
 *
 * Copyright (C) 1999 Masanao Izumo <[email protected]>
 * 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.

Также см. соответствующие вопросы: здесь и здесь

person Albert    schedule 13.03.2014
comment
Проголосуйте за понимание того, что такое декодирование UTF-8. - person rightfold; 10.09.2015
comment
Этот код неверен. fromCharCode принимает значения UTF-16, поэтому перед его вызовом необходимо преобразовать в UTF-16. - person Simon; 01.11.2017

Возможно, будет достаточно использовать textDecoder.

Однако не поддерживается в IE.

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

decodedMessage = decoder.decode(message.data);

Обработка текста, отличного от UTF8

В этом примере мы расшифровываем русский текст Привет, мир!, что означает Привет, мир. В нашем конструкторе 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 — это любая из перечисленных допустимых кодировок здесь.

person Jonathan    schedule 17.11.2016
comment
Это просто добавляет еще один слой беспорядка к существующему беспорядку. И экспериментальный. - person Álvaro González; 17.11.2016
comment
@ ÁlvaroGonzález Но это работает и может быть стандартным (будущие браузеры тоже должны будут это поддерживать, хорошо?) - person Klaider; 02.02.2017
comment
В настоящее время это не экспериментально, отлично поддерживается во всех современных браузерах и является абсолютно правильным выбором для всех (если вам все еще не нужно поддерживать IE). - person Tim Perry; 17.06.2020
comment
Что такое decodedMessage? - person Jamie Hutber; 15.01.2021
comment
Откуда я могу получить message.data? - person Jamie Hutber; 16.01.2021
comment
@JamieHutber Возможно, вы ищете это?: developer.mozilla.org/ en-US/docs/Web/API/TextDecoder - person Jonathan; 18.01.2021
comment
это не работает для строк, только для буферов массивов. - person Juan Vilar; 15.02.2021
comment
@JuanVilar Итак, у вас уже есть строка, закодированная определенным образом, которую вы можете затем использовать в textEncoder для преобразования ее в буфер массива, который затем можно использовать для преобразования ее в строку с желаемой кодировкой. - person Jonathan; 16.02.2021

Вот решение, обрабатывающее все кодовые точки Unicode, включая верхние (4 байта) значения и поддерживаемое всеми современными браузерами (IE и другие > 5.5). Он использует decodeURIComponent(), но НЕ устаревшие функции escape/unescape:

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.

person Matthew Voss    schedule 15.02.2017
comment
Был бы признателен за подробное описание аргументов и результатов. Юникод меня ужасно смущает. - person David Spector; 05.09.2019

Обновите ответ @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;
}
person lauthu    schedule 25.02.2017
comment
Примечание. Это работает с правильно сформированным вводом UTF-8, но прерывается без предварительного уведомления при некоторых условиях: например, предполагается, что осталось правильное количество байтов и что они имеют правильную последовательность продолжения 0b10xxxxxx, а в case 15 следует только соответствует 0b11110xxx, иначе он может декодировать недопустимую кодовую точку. - person some; 05.02.2020

Я думаю, что решение @albert было самым близким, но оно может анализировать только до 3-байтовых символов utf-8.

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

  out = "";
  len = array.length;
  i = 0;

  // XXX: Invalid bytes are ignored
  while(i < len) {
    c = array[i++];
    if (c >> 7 == 0) {
      // 0xxx xxxx
      out += String.fromCharCode(c);
      continue;
    }

    // Invalid starting byte
    if (c >> 6 == 0x02) {
      continue;
    }

    // #### MULTIBYTE ####
    // How many bytes left for thus character?
    var extraLength = null;
    if (c >> 5 == 0x06) {
      extraLength = 1;
    } else if (c >> 4 == 0x0e) {
      extraLength = 2;
    } else if (c >> 3 == 0x1e) {
      extraLength = 3;
    } else if (c >> 2 == 0x3e) {
      extraLength = 4;
    } else if (c >> 1 == 0x7e) {
      extraLength = 5;
    } else {
      continue;
    }

    // Do we have enough bytes in our data?
    if (i+extraLength > len) {
      var leftovers = array.slice(i-1);

      // If there is an invalid byte in the leftovers we might want to
      // continue from there.
      for (; i < len; i++) if (array[i] >> 6 != 0x02) break;
      if (i != len) continue;

      // All leftover bytes are valid.
      return {result: out, leftovers: leftovers};
    }
    // Remove the UTF-8 prefix from the char (res)
    var mask = (1 << (8 - extraLength - 1)) - 1,
        res = c & mask, nextChar, count;

    for (count = 0; count < extraLength; count++) {
      nextChar = array[i++];

      // Is the char valid multibyte part?
      if (nextChar >> 6 != 0x02) {break;};
      res = (res << 6) | (nextChar & 0x3f);
    }

    if (count != extraLength) {
      i--;
      continue;
    }

    if (res <= 0xffff) {
      out += String.fromCharCode(res);
      continue;
    }

    res -= 0x10000;
    var high = ((res >> 10) & 0x3ff) + 0xd800,
        low = (res & 0x3ff) + 0xdc00;
    out += String.fromCharCode(high, low);
  }

  return {result: out, leftovers: []};
}

Это возвращает {result: "parsed string", leftovers: [list of invalid bytes at the end]}, если вы анализируете строку по частям.

РЕДАКТИРОВАТЬ: исправлена ​​проблема, обнаруженная @unhammer.

person fakedrake    schedule 21.01.2016
comment
Когда я пробую это с [195,165], я получаю {"result":"","leftovers":[195, 165]}, а @Albert дает å - person unhammer; 14.11.2016
comment
Вы правы, я исправил это в своем проекте, но не в этом посте. Извините за мою небрежность. - person fakedrake; 14.11.2016
comment
Нет проблем, кажется, теперь работает :-) Забавно, что он уже получил два голоса, прежде чем кто-то его протестировал :-) Теперь utf8ArrayToStr([240,159,154,133]) дает мне мой ???? - person unhammer; 15.11.2016

// Строка в Utf8 ByteBuffer

function strToUTF8(str){
  return Uint8Array.from(encodeURIComponent(str).replace(/%(..)/g,(m,v)=>{return String.fromCodePoint(parseInt(v,16))}), c=>c.codePointAt(0))
}

// Utf8 ByteArray в строку

function UTF8toStr(ba){
  return decodeURIComponent(ba.reduce((p,c)=>{return p+'%'+c.toString(16),''}))
}
person user9642681    schedule 13.04.2018
comment
Может ли кто-нибудь проверить это? Кроме того, пожалуйста, подробно задокументируйте аргумент и возвращаемое значение, чтобы помочь тем из нас, кто запутался в Unicode. Спасибо. - person David Spector; 05.09.2019

Это то, что я нашел после более конкретного поиска в Google, чем просто кодирование/декодирование UTF-8. так что для тех, кто ищет библиотеку преобразования для преобразования между кодировками, вот вам.

https://github.com/inexorabletash/text-encoding

var uint8array = new TextEncoder().encode(str);
var str = new TextDecoder(encoding).decode(uint8array);

Вставить из файла readme репозитория

Поддерживаются все кодировки из спецификации Encoding:

utf-8 ibm866 iso-8859-2 iso-8859-3 iso-8859-4 iso-8859-5 iso-8859-6 iso-8859-7 iso-8859-8 iso-8859-8-i iso-8859- 10 iso-8859-13 iso-8859-14 iso-8859-15 iso-8859-16 koi8-r koi8-u macintosh windows-874 windows-1250 windows-1251 windows-1252 windows-1253 windows-1254 windows-1255 windows -1256 windows-1257 windows-1258 x-mac-cyrillic gb18030 hz-gb-2312 big5 euc-jp iso-2022-jp shift_jis euc-kr замена utf-16be utf-16le x-user-defined

(Некоторые кодировки могут поддерживаться под другими именами, например, ascii, iso-8859-1 и т. д. Дополнительные метки для каждой кодировки см. в разделе Кодировка.)

person Olle Tiinus    schedule 26.02.2019
comment
Это лучший способ для меня. Спасибо, для получения дополнительной информации нажмите developer.mozilla.org/en-US/docs/Web/API/TextDecoder/ - person henrry; 16.06.2020
comment
.encode не является функцией - person Jamie Hutber; 16.01.2021

Используя мою 1,6 КБ библиотеку, вы можете сделать

ToString(FromUTF8(Array.from(usernameReceived)))
person MCCCS    schedule 24.01.2019

Я считаю, что самым простым способом было бы использовать встроенные функции js decodeURI()/encodeURI().

function (usernameSent) {
  var usernameEncoded = usernameSent; // Current value: utf8
  var usernameDecoded = decodeURI(usernameReceived);  // Decoded
  // do stuff
}
person Kasparow    schedule 02.03.2018
comment
Звучит легко. Слишком легко. Вы проверяли это? - person David Spector; 05.09.2019

Это решение с расширенными отчетами об ошибках.

Он будет принимать массив байтов в кодировке UTF-8 (где массив байтов представлен в виде массива чисел, и каждое число является целым числом от 0 до 255 включительно) и будет создавать строку JavaScript из символов Unicode.

function getNextByte(value, startByteIndex, startBitsStr, 
                     additional, index) 
{
    if (index >= value.length) {
        var startByte = value[startByteIndex];
        throw new Error("Invalid UTF-8 sequence. Byte " + startByteIndex 
            + " with value " + startByte + " (" + String.fromCharCode(startByte) 
            + "; binary: " + toBinary(startByte)
            + ") starts with " + startBitsStr + " in binary and thus requires " 
            + additional + " bytes after it, but we only have " 
            + (value.length - startByteIndex) + ".");
    }
    var byteValue = value[index];
    checkNextByteFormat(value, startByteIndex, startBitsStr, additional, index);
    return byteValue;
}

function checkNextByteFormat(value, startByteIndex, startBitsStr, 
                             additional, index) 
{
    if ((value[index] & 0xC0) != 0x80) {
        var startByte = value[startByteIndex];
        var wrongByte = value[index];
        throw new Error("Invalid UTF-8 byte sequence. Byte " + startByteIndex 
             + " with value " + startByte + " (" +String.fromCharCode(startByte) 
             + "; binary: " + toBinary(startByte) + ") starts with " 
             + startBitsStr + " in binary and thus requires " + additional 
             + " additional bytes, each of which shouls start with 10 in binary."
             + " However byte " + (index - startByteIndex) 
             + " after it with value " + wrongByte + " (" 
             + String.fromCharCode(wrongByte) + "; binary: " + toBinary(wrongByte)
             +") does not start with 10 in binary.");
    }
}

function fromUtf8 (str) {
        var value = [];
        var destIndex = 0;
        for (var index = 0; index < str.length; index++) {
            var code = str.charCodeAt(index);
            if (code <= 0x7F) {
                value[destIndex++] = code;
            } else if (code <= 0x7FF) {
                value[destIndex++] = ((code >> 6 ) & 0x1F) | 0xC0;
                value[destIndex++] = ((code >> 0 ) & 0x3F) | 0x80;
            } else if (code <= 0xFFFF) {
                value[destIndex++] = ((code >> 12) & 0x0F) | 0xE0;
                value[destIndex++] = ((code >> 6 ) & 0x3F) | 0x80;
                value[destIndex++] = ((code >> 0 ) & 0x3F) | 0x80;
            } else if (code <= 0x1FFFFF) {
                value[destIndex++] = ((code >> 18) & 0x07) | 0xF0;
                value[destIndex++] = ((code >> 12) & 0x3F) | 0x80;
                value[destIndex++] = ((code >> 6 ) & 0x3F) | 0x80;
                value[destIndex++] = ((code >> 0 ) & 0x3F) | 0x80;
            } else if (code <= 0x03FFFFFF) {
                value[destIndex++] = ((code >> 24) & 0x03) | 0xF0;
                value[destIndex++] = ((code >> 18) & 0x3F) | 0x80;
                value[destIndex++] = ((code >> 12) & 0x3F) | 0x80;
                value[destIndex++] = ((code >> 6 ) & 0x3F) | 0x80;
                value[destIndex++] = ((code >> 0 ) & 0x3F) | 0x80;
            } else if (code <= 0x7FFFFFFF) {
                value[destIndex++] = ((code >> 30) & 0x01) | 0xFC;
                value[destIndex++] = ((code >> 24) & 0x3F) | 0x80;
                value[destIndex++] = ((code >> 18) & 0x3F) | 0x80;
                value[destIndex++] = ((code >> 12) & 0x3F) | 0x80;
                value[destIndex++] = ((code >> 6 ) & 0x3F) | 0x80;
                value[destIndex++] = ((code >> 0 ) & 0x3F) | 0x80;
            } else {
                throw new Error("Unsupported Unicode character \"" 
                    + str.charAt(index) + "\" with code " + code + " (binary: " 
                    + toBinary(code) + ") at index " + index
                    + ". Cannot represent it as UTF-8 byte sequence.");
            }
        }
        return value;
    }
person Yordan Nedelchev    schedule 27.03.2020

Вы должны взять decodeURI за это.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURI

Вот так просто:

decodeURI('https://developer.mozilla.org/ru/docs/JavaScript_%D1%88%D0%B5%D0%BB%D0%BB%D1%8B');
// "https://developer.mozilla.org/ru/docs/JavaScript_шеллы"

Попробуйте использовать его внутри блока try catch, чтобы не пропустить URIError.

Также он имеет полную поддержку браузеров.

person Vadim Shvetsov    schedule 24.09.2020

Предпочтительно, как предлагали другие, использовать Encoding API. Но если вам нужна поддержка IE (по какой-то странной причине), MDN рекомендует этот репозиторий FastestSmallestTextEncoderDecoder.

Если вам нужно использовать библиотеку полифилла:

    import {encode, decode} from "fastestsmallesttextencoderdecoder";

Затем (независимо от полифилла) для кодирования и декодирования:

    // takes in USVString and returns a Uint8Array object
    const encoded = new TextEncoder().encode('€')
    console.log(encoded);

    // takes in an ArrayBuffer or an ArrayBufferView and returns a DOMString
    const decoded = new TextDecoder().decode(encoded);
    console.log(decoded);
person geremews    schedule 05.05.2021
comment
Ссылка на решение приветствуется, но убедитесь, что ваш ответ полезен и без нее: добавьте контекст вокруг ссылки, чтобы другие пользователи иметь некоторое представление о том, что это такое и почему оно там, а затем процитировать наиболее важную часть страницы, на которую вы ссылаетесь, в случае, если целевая страница недоступна. Ответы, которые представляют собой не более чем ссылку, могут быть удалены. - person 10 Rep; 06.05.2021
comment
Хотя эта ссылка может ответить на вопрос, лучше включить сюда основные части ответа и предоставить ссылку для справки. Ответы, содержащие только ссылки, могут стать недействительными, если связанная страница изменится. – Из обзора - person 10 Rep; 06.05.2021

Я искал простое решение, и это хорошо работает для меня:

//input data
view = new Uint8Array(data);

//output string
serialString = ua2text(view);

//convert UTF8 to string
function ua2text(ua) {
    s = "";
    for (var i = 0; i < ua.length; i++) {
        s += String.fromCharCode(ua[i]);
    }
    return s;               
}

Единственная проблема, которая у меня есть, это то, что иногда я получаю по одному персонажу за раз. Это может быть задумано с моим источником буфера массива. Я использую https://github.com/xseignard/cordovarduino для чтения последовательных данных на устройстве Android. .

person Evan Grant    schedule 12.08.2015
comment
На самом деле это не декодирует UTF-8. Например, C3 BC должно быть расшифровано как ü, но ваш ответ возвращает ü. - person phihag; 02.01.2016