如何从REST API正确获取并处理WebAssembly(.wasm)文件?
问题描述
我正在开发一个Next.js应用,页面需要连接REST API,该API直接返回原始WebAssembly(.wasm)文件。我编写了如下获取.wasm文件的函数:
const fetchedWasmWrapped = useCallback( async () => { const endpoint = "/.netlify/functions" + "/decrypt?authSig="+JSON.stringify(props.props.authSig); const options = { method: 'GET', headers: { 'Content-Type': 'application/wasm', }, }; const response = await fetch(endpoint, options); const result = await response.text(); console.log(result); setDecryptedWasm(result); }, [props.props.authSig])
该函数可获取文件,但console.log(result)输出大量乱码。因WebAssembly是二进制Blob,不应以字符串读取,后续文件读取也失败了。请问如何在TypeScript中正确从response获取.wasm代码?
解决方案
你遇到的问题核心是用response.text()解析二进制的wasm文件,这会把二进制数据当作UTF-8字符串处理,导致数据损坏和乱码。正确的做法是直接读取二进制数据,再编译为WebAssembly模块,以下是两种可行的实现方式:
方式一:读取为ArrayBuffer并编译
const fetchedWasmWrapped = useCallback(async () => { const endpoint = "/.netlify/functions/decrypt?authSig=" + JSON.stringify(props.props.authSig); const options = { method: 'GET', headers: { 'Accept': 'application/wasm', // 用Accept头明确告知服务器期望的响应类型 }, }; const response = await fetch(endpoint, options); // 先检查响应是否成功 if (!response.ok) { throw new Error(`请求失败: ${response.status} ${response.statusText}`); } // 直接读取二进制ArrayBuffer const wasmBuffer = await response.arrayBuffer(); // 编译WebAssembly模块 const wasmInstance = await WebAssembly.instantiate(wasmBuffer); // 如果你需要保存原始二进制数据到状态 setDecryptedWasm(wasmBuffer); // 可以调用wasm导出的方法,比如 wasmInstance.instance.exports.yourExportedFunction() }, [props.props.authSig]);
方式二:读取为Blob再转ArrayBuffer
如果需要对二进制数据做Blob相关的操作(比如下载、存储),可以先读取为Blob:
const fetchedWasmWrapped = useCallback(async () => { const endpoint = "/.netlify/functions/decrypt?authSig=" + JSON.stringify(props.props.authSig); const options = { method: 'GET', headers: { 'Accept': 'application/wasm', }, }; const response = await fetch(endpoint, options); if (!response.ok) { throw new Error(`请求失败: ${response.status} ${response.statusText}`); } const wasmBlob = await response.blob(); const wasmBuffer = await wasmBlob.arrayBuffer(); const wasmInstance = await WebAssembly.instantiate(wasmBuffer); setDecryptedWasm(wasmBuffer); // 或保存blob:setDecryptedWasm(wasmBlob) }, [props.props.authSig]);
关键修改说明
- 替换读取方式:将
response.text()改为response.arrayBuffer()或response.blob(),直接获取二进制数据,避免字符串解析导致的损坏。 - 修正请求头:GET请求不需要设置
Content-Type(该头用于定义请求体的类型,GET无请求体),换成Accept: application/wasm更合理,明确告诉服务器我们需要的响应格式。 - 添加错误处理:检查
response.ok确保请求成功,避免处理无效的响应数据。 - 编译wasm模块:使用
WebAssembly.instantiate()将二进制数据编译为可执行的wasm实例,这样就能调用其中导出的方法。
内容的提问来源于stack exchange,提问作者ChristianOConnor
相关产品推荐
相关产品推荐

