.NET6 Blazor WASM嵌入iframe项目平板端报body流已读取错误
问题根因
WebAssembly.instantiateStreaming执行时会直接读取Response的body流,而Response流是只能读取一次的可消耗流,平板端浏览器未实现流的自动缓存/克隆逻辑,所以fallback到ArrayBuffer分支时再次读取就会报流已被读取的错误- 你提供的代码片段存在语法疏漏:
then回调没有返回arrayBuffer()的执行结果,导致变量n为undefined,进而触发第二个参数格式错误
修复方案
方案1:修正自定义instantiateWasm逻辑
先克隆Response流再执行流式编译,保证fallback分支可以读取到完整的流数据,同时补全return逻辑,修复后的代码如下:
return s.instantiateWasm = (e,t)=>((async()=>{ let n; try { const t = await u; n = await async function(e, t) { if ("function" == typeof WebAssembly.instantiateStreaming) { try { // 先克隆Response再传入流式编译,原Response留作fallback使用 return (await WebAssembly.instantiateStreaming(e.response.clone(), t)).instance } catch (e) { console.info("Streaming compilation failed. Falling back to ArrayBuffer instantiation. ", e) } } // 补全return语句返回arrayBuffer结果 const n = await e.response.then((e=> e.arrayBuffer())); return (await WebAssembly.instantiate(n, t)).instance }(t, e) } catch (e) { throw s.printErr(e.toString()), e } t(n) }))()
方案2:针对iframe嵌入场景强制关闭流式编译
如果是面向平板端的兼容场景,可直接关闭Blazor WASM的流式编译能力,避免分支判断带来的兼容性问题,只需在项目wwwroot/index.html的Blazor启动逻辑中添加配置即可:
Blazor.start({ wasmOptions: { disableStreaming: true } });
注意事项
- 若平板端使用的是15版本以下的Safari浏览器,该版本对Wasm流式编译存在已知兼容bug,直接使用方案2即可解决问题
- 修复上线前需清空平板端浏览器缓存、PWA存储以及ServiceWorker注册信息,避免旧资源缓存影响验证结果
内容的提问来源于stack exchange,提问作者Thant Zin Tun
相关产品推荐
相关产品推荐

