DEBUG.WIKI
晚安云;香港 CN2 ¥15/月
IPPeak:从目标地区访问网页,住宅代理、SEO 监测、广告验证
搬瓦工;先看线路,再选 VPS;CN2 GIA · 对应线路套餐;查看线路 →

Deno Desktop 返回 Uint8Array,绑定调用却报 invalid type: byte array

Deno Desktop旧绑定通道将二进制经过JSON值,Uint8Array返回时报byte array错误。核对运行时与laufey两侧正式修复,有限数据可临时走经过校验的数值数组。

Desktop 的字符串绑定能正常返回,换成 Uint8Array 后,网页端的 Promise 却拒绝:

TypeError: invalid type: byte array, expected any valid JSON value

已确认的形态涉及 Deno 2.9.4、2.9.5 与 laufey 0.6.1 的 Desktop 通信。错误发生在绑定参数或返回值跨运行时传输时,和读取文件是否成功是两回事。即使只返回几个固定字节,也可能遇到它。

二进制不能经过只接受 JSON 值的那条通道

下面的片段放在应用已经创建好的 Desktop 窗口 win 上,用来说明返回值形态:

win.bind('readBytes', async () => {
  return new Uint8Array([1, 2, 3, 255]);
});

旧传输层使用 JSON 值承接绑定数据,字节数组进入这条序列化路径时会失败。反方向传入 Uint8Array 还可能变成按数字键展开的普通对象。前端声明了某个返回类型,不会改变这层实际传输方式。

因此,先用普通字符串或普通数组与同一个绑定入口对照。如果它们成功,而类型数组触发上面的字节反序列化错误,应检查 Desktop 两端的传输版本;没有必要先扩大文件权限或换文件格式。

运行时与窗口后端都要包含修复

这项修正分成两侧:Deno 运行时需要用能保留二进制的值类型跨过绑定通道,窗口后端也要正确识别输入字节,并向网页交付约定的 Uint8Array。只修一侧,可能从原来的硬错误变成 ArrayBuffer 或数字键对象,仍然不符合应用契约。

截至 2026 年 10 月 23 日,正式 Deno 2.9.8 的运行时源码已包含二进制绑定传输实现,锁定的 laufey 为 0.7.0;laufey 0.7.0 也已包含两种后端的相应修正。它们是可以核对的正式组合,不代表单独替换任意一个开发后端就能得到相同结果。

更新时检查实际启动的 Deno 二进制,以及应用使用的后端产物。若配置了自编译或单独指定的后端目录,不能只看运行时版本号;也不要手改依赖缓存里的 JavaScript 来伪装返回类型。

零长度二进制还需单独处理:laufey 0.7.0 的 CEF 输入分支可能把空视图转换为 null,webview 的转换条件也可能留下空二进制标记对象。不能把这组修复理解为所有空 Uint8Array 都能保真往返。应用应明确空数据的表示,例如使用经过校验的普通空数组,不能把意外收到的 null 默认为有效的空字节。

其他类型数组的视图类型并不会因此自动保留。例如业务需要 Float64Array 时,应有明确的类型与字节协议,再由接收端恢复;不能只因字节长度相同,就把 Uint8Array 当成原始数值数组使用。

小数据可以暂时用普通数值数组传输

无法立即协调两端版本时,可把有限的字节数据明确转成普通数组,让接收端校验后再恢复。以下仍使用已有窗口绑定,不涉及真实文件读取:

// Deno 侧
win.bind('readBytes', async () => {
  const bytes = new Uint8Array([1, 2, 3, 255]);
  return Array.from(bytes);
});

网页端拿到返回值后,先确认它是数组、长度在应用允许范围内,并且每项都是 0 到 255 的整数,再调用 new Uint8Array(value)。这些检查应发生在构造之前,因为构造器会转换输入,不能靠转换后的结果反证原数据有效。

这条规避会改变传输表示,适合有明确体积上限的数据;不要把大文件整份展开成数值数组而忽略内存和消息体积。若字节来自子视图,Array.from(bytes) 处理的是当前视图中的元素,不要误传整个底层 buffer 中不属于该片段的数据。

最终按原入口分别核对两个方向:字节内容和长度准确,接收类型符合约定,错误能传回调用方。分别检查普通空数组、零长度类型数组,以及包含 0 和 255 的非空样本,并检查普通 JSON 对象仍正常;空二进制未满足约定时,应明确走应用的兼容表示或失败分支。只看到 Promise 不再拒绝,不能证明二进制语义已经保留。