javascript - 如何在纯 JavaScript 中发送二进制数据?
问题描述
我想通过 JavaScript 将二进制数据从 html 页面发送到我的服务器,但服务器收到的字节不同。接收到的字节似乎被转换为 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├¥┬Ç
。
任何提示如何接收原始二进制数据都会很棒。
解决方案
恕我直言,我的 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
是 aDocument
,则将请求正文设置为body
、序列化、转换为 Unicode 和 UTF-8 编码。否则,将请求正文设置
extractedContentType
为提取的结果body
。
String
不是 a Document
,因此第一个选项不适用。“提取”的定义可在fetch
规范中找到:
USV字符串:
设置
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]
推荐阅读
- python - 检查 mongodb / python 中列的内容
- python - Python:有没有什么方法可以在写入下一行之前等待几秒钟写入输出文件?
- angular - 当我使用 HttpInterceptor 添加标头时,它们被添加到lazyUpdate,而不是标头数组
- ruby-on-rails - rails6中的单表继承
- flask-mongoengine - 如何使用 flask-mongodb 查询数据并按日期过滤
- python - 防止 Python 自动“截断”嵌套元组
- c# - 将项目添加到 ObservableCollection 时的 WPF 事件
- python - 如何将消耗内存的计算拆分为多个部分,然后保存和加载每个部分?
- c - Cygwin64 终端:未定义对 `mbuf_remove` 的引用
- sql-server - 我的维护计划中的某些数据库不会备份,并出现错误“操作系统错误代码 3(系统找不到指定路径)”