Как отправить двоичные данные в чистом JavaScript? - PullRequest
0 голосов
/ 25 февраля 2019

Я хочу отправить двоичные данные со страницы html на мой сервер через JavaScript, но сервер получил не те же байты.Полученные байты, похоже, преобразуются в строку Unicode, см. Следующий пример:

xhr.open('POST', '/check', true);
xhr.setRequestHeader('cache-control', 'no-cache');
xhr.setRequestHeader('Content-Type', 'application/octet-stream');
xhr.send('\x41\xFE\x80');

Сервер должен получить 'Aþ €', но он получает A├¥┬Ç.

Я проверилмного вещей, таких как:

//xhr.overrideMimeType('text/plain; charset=iso-8859-1');
//xhr.setRequestHeader('Content-type', 'text/plain; charset=iso-8859-1');
//xhr.setRequestHeader('Content-type', 'application/xml; charset=UTF-8');
//xhr.overrideMimeType('text/plain; charset=x-user-defined');
//xhr.overrideMimeType('text\/plain; charset=x-user-defined');

На стороне сервера я запускаю plackup (http://localhost:5000/index.html), и $env->{'CONTENT_LENGTH'} равно 5, поэтому сервер действительно, кажется, получает5 байтов A├¥┬Ç.

Любой намек на получение исходных двоичных данных был бы полезен.

1 Ответ

0 голосов
/ 25 февраля 2019

ИМХО мой Javascript правильный

Это не так.Как я намекал в комментарии, используйте Uint8Array, а не строки, для двоичных данных:

xhr.send(new Uint8Array([0x41, 0xFE, 0x80]));

Если у вас уже есть строка ... это должно работать:

xhr.send(new Uint8Array(Array.from('\x41\xFE\x80').map(x => x.charCodeAt(0)))

Объяснение: спецификация для send гласит:

Если body является Document, тогда установите тело запроса на body, сериализованное, преобразованное в Unicodeи в кодировке UTF-8.

В противном случае установите тело запроса и extractedContentType для результата извлечения body.

String не является Document,поэтому первый вариант не применяется.Определение «извлечения» находится в fetch spec :

USVString:

Установить action на действие, которое запускает UTF-8кодировать на object.

Установить Content-Type на text/plain;charset=UTF-8.

Установить source на object.

И вы можете увидеть, какКодировка UTF-8 вашей строки выглядит следующим образом:

new TextEncoder().encode('\x41\xFE\x80')
// => Uint8Array(5) [65, 195, 190, 194, 128]
...