WebAssembly InstantiateStreaming 错误的 MIME 类型
我正在尝试获取本教程(此处:https://www.hellorust.com/demos/add/index.html) 工作,似乎无论我做什么,我都无法让 WebAssembly MDN 保留功能正常工作.
I am attempting to get this tutorial (here: https://www.hellorust.com/demos/add/index.html) to work, and it seems that whatever I do, I cannot get the WebAssembly MDN reserved function to properly work.
所以,我按照上面链接上的说明获得了一个 add.wasm
文件.据我所知,这应该相当简单并且应该可以工作.经过一番挖掘,我发现最新的 WebAssembly 模块是用于实例化流 - 可以在此处找到其文档:(https://developer.mozilla.org/en-US/docs/WebAssembly/Using_the_JavaScript_API).
So, I followed the instructions on the link above and got an add.wasm
file. As far as I can tell this should be fairly simple and should work. After a little digging I found that the newest WebAssembly module is to instantiate streaming - the documentation for which can be found here: (https://developer.mozilla.org/en-US/docs/WebAssembly/Using_the_JavaScript_API).
MDN 示例说要执行以下操作:
The MDN example says to do the following:
var importObject = {
imports: { imported_func: arg => console.log(arg) }
};
然后
WebAssembly.instantiateStreaming(fetch('simple.wasm'), importObject)
.then(obj => obj.instance.exports.exported_func());
根据 MDN,importObject 用于解开嵌套参数.很奇怪,但还可以.
According to MDN the importObject is to unwrap the nested argument. Weird, but OK.
为了使这尽可能简单,我将 add.wasm
文件和将导入它的 js
文件放在同一目录中,然后按照 (注意:我使用的是 Vue.js,但对于任何熟悉 SPA 类库的人来说,这应该是相似的):
To make this as simple as possible I put the add.wasm
file and the js
file that would import it in the same directory and then did then following (NOTE: I am using Vue.js, but for anyone familiar with SPA like libraries this should be similar):
window.WebAssembly.instantiateStreaming(fetch('./add.wasm', {
headers: {
"Content-Type": "application/wasm",
},
}), importObject)
.then(obj => {
console.log('inside return obj from WebAssembly initiateStreaming')
obj => obj.instance.exports.exported_func()
})
.catch(error=>{
console.log('there was some error; ', error)
});
我得到的错误是:
there was some error; TypeError: "Response has unsupported MIME type"
我尝试不将标头添加到获取请求中,使用 fetch(add.wasm)
,删除 window.
,删除 importObject
完全简单地将 obj
记录到控制台.似乎没有任何效果.
I've tried not adding the header to the fetch request, using fetch(add.wasm)
, dropping the window.
, dropping the importObject
entirely and simple logging obj
to console. Nothing appears to work.
如果 application/wasm
字段未得到广泛支持,我可能必须以某种方式将其添加到 webpack,但我不确定,我还没有在网上看到任何示例.
It may be that I have to add the application/wasm
field to webpack somehow if it is not widely supported, but I'm not sure and I haven't seen any examples online.
有谁知道如何让它工作?
Does anyone know how to get this to work?
有人建议,由于这是一个获取请求,它必须从后端服务器发出请求.这对我来说很有意义,所以我做了以下事情:
Someone suggested that since this was a fetch request it had to be making the request from a backend server. This made sense to me, so I did the following:
WebAssembly.instantiateStreaming(fetch('http://localhost:8000/files/add.wasm'), importObject)
.then(obj => {
console.log('inside return obj from WebAssembly initiateStreaming')
obj => obj.instance.exports.exported_func()
})
.catch(error=>{
console.log('there was some error; ', error)
});
其中 http://localhost:8000/files/{someFile}
是为我的文件提供服务的后端路由(我确保将 add.wasm
放入当然).不幸的是,我得到了同样的错误(即 unrecognized MIME type
),我不知道为什么.
Where http://localhost:8000/files/{someFile}
is a backend route that serves my files (which I made sure to put add.wasm
in of course). Unfortunately, I get the same error (i.e. unrecognized MIME type
) and I'm not sure why.
推荐答案
考虑到你无法更改服务器以正确返回 .wasm
文件请求的 application/wasm
无论出于何种原因,您都可以通过更改实例化 WebAssembly 模块的方式来解决此问题.而不是这样做:
Considering you can't change the server to properly return application/wasm
for .wasm
file requests for any reason, you can work around the issue by changing the way you instantiate the WebAssembly module. Instead of doing this:
WebAssembly.instantiateStreaming(fetch("./add.wasm")).then(obj => /* ... */)
这样做:
const response = await fetch("add.wasm");
const buffer = await response.arrayBuffer();
const obj = await WebAssembly.instantiate(buffer);
obj.instance.exports.exported_func();
如果您不能使用 async/await
,则使用 then()
的等效项.
Or the equivalent using then()
if you cannot use async/await
.
实际上,我的解决方法是避免调用 instantiateStreaming()
,它必须在继续之前检查服务器返回的 MIME 类型(根据 本规范).相反,我调用 instantiate()
并传递一个 ArrayBuffer
并完全避免检查.
In practice, what my workaround does is to avoid calling instantiateStreaming()
, which must check the MIME type returned by the server before proceeding (according to this specification). Instead, I call instantiate()
passing an ArrayBuffer
and avoid the check altogether.
相关文章