Обзор
В прошлом блоге мы говорили о том, как выполнить бинарное преобразование числовых типов (таких как Short, Int и Long) в JavaScript, Если вам интересно, вы можете прочитать второй блог из этой серии —Как преобразовать цифровые данные в двоичные данные в JavaScript в серии WebSocket. На этот раз поговорим о том, как работать с данными строкового типа. Эта статья является третьей частью серии WebSocket. В ней в основном представлен метод преобразования между строковыми данными и двоичными данными. Конкретное содержание выглядит следующим образом:
- Базовые знания строкового типа в JavaScript.
- Как преобразовать строковый тип в двоичные данные в JavaScript
- JavaScript如何将二进制数据转换为string类型 Эта статья не слишком тесно связана с WebSocket, но как базовая база знаний для передачи двоичных данных в WebSocket включена в эту серию. 如果读者对WebSocket并不了解,或者说不明白它的使用场景和细节,可以阅读我的本系列的第一篇博客——Введение в базовые знания серии WebSocket.
Базовые знания о типах строк
Этот тип строки должен быть знаком учащимся, знакомым с JavaScript, так как это один из основных типов данных в JavaScript. Однако сегодня мы собираемся представитьDOMString
.
DOMString — это строка UTF-16. Так как JavaScript уже использует такие строки, DOMString напрямую сопоставляется со строкой. Передача null методу или параметру, который принимает DOMString, обычно преобразует его в «null».
При выполнении передачи данных строкового типа в WebSocket фактически используетсяDOMString
. Однако, согласноMDNсредняя параDOMString
Из введения мы можем понять, что в большинстве сценариев повседневного использования мы можем думать, чтоDOMString
является строковым типом. Следовательно, нам нужно только понять этот тип и по-прежнему обращаться с ним как со строковым типом при его использовании.
кодирование
Поскольку выше упоминалась UTF-16, давайте кратко представим UTF-16 и UTF-8, которые обычно используются в бэкэнде. Зачем нам нужно вводить типы кодирования? Потому что мы можем использовать разные методы кодирования при передаче строковых данных с серверной частью, что приведет к тому, что две стороны получат разные данные. Поэтому, когда мы передаем двоичные данные строки, нам нужно не только преобразовать строку в двоичную, но также требуется согласованная кодировка строки.
UTF-16
UTF-16 (16-битный формат преобразования Unicode) — это третий уровень пятиуровневой модели кодирования символов Unicode: реализация формы кодирования символов (форма кодирования символов, также известная как «формат хранения»). То есть абстрактные кодовые точки набора символов Unicode отображаются в последовательность 16-битных целых чисел (т. е. единиц кода) для хранения или передачи данных. Кодовая точка символа Unicode требует для представления одной или двух 16-битных кодовых единиц, поэтому это представление переменной длины.
UTF-16 — это тип кодировки строк в JavaScript.
UTF-8
UTF-8 (8-битный формат преобразования Unicode) — это кодировка символов переменной длины для Unicode и код префикса. Его можно использовать для представления любого символа стандарта Unicode, и первый байт в его кодировке по-прежнему совместим с ASCII, что позволяет продолжать использовать исходное программное обеспечение, обрабатывающее символы ASCII, без модификаций или с некоторыми изменениями. UTF-8 кодирует каждый символ с использованием от одного до четырех байтов (перенормировано в ноябре 2003 г.).
UTF-8 — это распространенный тип кодировки, используемый многими языками и очень распространенный в серверных приложениях.
Как преобразовать кодировку UTF16 и UTF-8 в JavaScript
На Github есть библиотека конвертацииGitHub - dcodeIO/utfx: A compact library to encode, decode and convert UTF8 / UTF16 in JavaScript.
import utfx from './util/utfx';
let str = 'abcdefg';
let result = [];
function stringSource(s) {
let i = 0;
return function () {
return i < s.length ? s.charCodeAt(i++) : null;
};
}
utfx.encodeUTF16toUTF8(stringSource(str), function (b) {
result.push(b);
}.bind(this));
Точно так же эта библиотека классов предоставляет другие методы:
-
decodeUTF8toUTF16
, который преобразует строковые данные UTF-8 в строковые данные UTF-16. -
calculateUTF16asUTF8
, рассчитайте длину в байтах, занимаемую типом строки в кодировке UTF-16, преобразованной в UTF-8. Мы будем использовать эти два метода в последующих главах.
Как преобразовать строковый тип в двоичные данные в JavaScript
Зная кодировку строкового типа в JavaScript и способ преобразования кодировки между UTF-8 и UTF-16, давайте посмотрим, как преобразовать строковый тип в двоичные данные. Прежде всего, мы предполагаем, что при взаимодействии с бэкендом используется кодировка UTF-8, которая может соответствовать большему количеству сценариев использования. Если вы все еще используете UTF-16, просто игнорируйте логику преобразования кодировки. Краткое введение в идею реализации: после того, как мы получили строку, которую необходимо преобразовать, мы сначала узнаем ее длину, инициализируем соответствующие параметры в ArrayBuffer и помещаем данные в ArrayBuffer. Немного изменим приведенный выше пример:
import utfx from './util/utfx';
function stringSource(s) {
var i = 0;
return function () {
return i < s.length ? s.charCodeAt(i++) : null;
};
}
let str = 'abcdefg';
let strCodes = stringSource(str);
let length = utfx.calculateUTF16asUTF8(strCodes)[1];
let buffer = new ArrayBuffer(length + 4); // 初始化长度为UTF8编码后字符串长度+4个Byte的二进制缓冲区
let view = new DataView(buffer);
let offset = 4;
view.setUint32(0, length); // 将长度放置在字符串的头部
utfx.encodeUTF16toUTF8(stringSource(str), function (b) {
view.setUint8(offset++, b);
}.bind(this));
В приведенном выше примере мы уже закодировали двоичные данные в соответствии с UTF-8 и поместили их в ArrayBuffer, и в то же время сохранили их длину как тип Unsigned Int в позиции 4 байта двоичного заголовка.
Как JavaScript преобразует двоичные данные в строковый тип
Зная, как преобразовать строковый тип в двоичные данные, давайте посмотрим, как прочитать все данные из двоичного и обратно преобразовать в строковый тип. В соответствии с описанным выше процессом преобразования в двоичный, нам нетрудно подумать о методах, связанных с двоичным и строковым типами. Конкретные примеры следующие:
import utfx from './util/utfx';
let str = 'abcdefg';
function stringSource(s) {
var i = 0;
return function () {
return i < s.length ? s.charCodeAt(i++) : null;
};
}
let strCodes = stringSource(str);
let length = utfx.calculateUTF16asUTF8(strCodes)[1];
let buffer = new ArrayBuffer(length + 4); // 初始化长度为UTF8编码后字符串长度+4个Byte的二进制缓冲区
let view = new DataView(buffer);
let offset = 4;
// 字符串转换二进制过程
view.setUint32(0, length); // 将长度放置在字符串的
utfx.encodeUTF16toUTF8(stringSource(str), function (b) {
view.setUint8(offset++, b);
}.bind(this));
// 二进制转换字符串过程
let Strlength = view.getUint32(0);
offset = 4;
let result = []; // Unicode编码字符
let end = offset + Strlength;
utfx.decodeUTF8toUTF16(function () {
return offset < end ? view.getUint8(offset++) : null; // 返回null时会退出此转换函数
}.bind(this), (char) => {
console.log(char)
result.push(char);
});
let strResult = result.reduce((prev, next)=>{
return prev + String.fromCharCode(next);
}, '');
Из приведенного выше примера мы можем знать, что нам нужно только прочитать длину строки в первых 4 байтах, а затем прочитать кодировку символов строки с указанной длиной с позиции 4-го байта (считая с 0) , Вот и все. Наконец, мы получаем массив кодов Unicode, просто нужноfromCharCode
метод преобразования его в строку.
Суммировать
Используя ArrayBuffer и DataView, мы можем преобразовывать строковые данные в двоичные. С соответствующей основой преобразования типа строки читатели могут понять соответствующий контент и логику обработки, когда WebSocket будет выполнять передачу двоичных данных в будущем. В следующем блоге из серии WebSocket будет рассказано, как передавать двоичные данные в серверную часть через WebSocket и как обрабатывать двоичные данные, полученные через WebSocket. Заинтересованные студенты могут продолжать обращать внимание.