【问题标题】:Invalid or unexpected token in WebAssemblyWebAssembly 中的无效或意外令牌
【发布时间】:2019-05-22 20:49:21
【问题描述】:

我正在尝试使用 Rocket 运行一个 WebAssembly 程序(用 Rust 编写,来自https://rustwasm.github.io/book/game-of-life/hello-world.html 的示例程序)。 WebAssembly 使用 wasm-pack 编译并使用 wasm_bindgen。 wasm 二进制文件在 Rocket 中表示为content::JavaScript<Vec<u8>>,这似乎是一个“有效”的解决方案。二进制文件已“正确”获取,但 Chrome 会打印 Uncaught SyntaxError: Invalid or unexpected token。这是由于content::JavaScript<Vec<u8>> 表示在获取期间出现错误(尽管发送字节与 wasm 文件中的字节匹配)还是其他地方的错误?

我希望有人能解释一下为什么生成的二进制文件中有 SyntaxError。

【问题讨论】:

    标签: webassembly rust-rocket


    【解决方案1】:

    好的,现在我想我知道出了什么问题: 从 wasm-pack 生成的 js 文件尝试将 WebAssembly 作为模块加载。该模块需要有一个 Javascript mime,否则它将失败(这就是为什么我试图将 wasm 文件发送为content::JavaScript<Vec<u8>>),但显然不支持加载一个 wasm 作为模块(如果我错了,请纠正我)所以当然它会在二进制文件中找到无效的令牌,因为它试图将其解释为纯 javascript。我现在实际使用的是来自 Rocket 女巫的 Option<NamedFile> 类型有一个 application/wasm mime。
    我需要稍微更改生成的 js 文件:WebAssembly 使用 WebAssembly.instatiateStreaming(fetch(...), importObjects) 初始化,然后模块导入应该是删除。 importObjects 也有点棘手,因为将 strigns 传递给 WebAssembly 有点不方便。对于可以从 WebAssembly 调用的警报函数,importObjects 如下所示:
    let importObjects = {'./wasm_test': { __wbg_alert_3d9cbee15c16469e: __wbg_alert_3d9cbee15c16469e }};
    名称来自 wasm 二进制文件:(import "./wasm_test" "__wbg_alert_3d9cbee15c16469e" (func $__wbg_alert_3d9cbee15c16469e (type $t0)))
    函数 __wbg_alert_3d9cbee15c16469e 由wasm 包。最后要更改的是最初通过import 语句导入的对象。我现在有一个变量,其中包含来自 obj.instance.exports 的内容,该变量是在 WebAssembly.instatiateStreaming(fetch(...), importObjects).then(obj => { wasm = obj.instance.exports; })
    的 then 语句中设置的 通过这些更改,它对我有用(向/从 WebAssembly 发送和读取字符串)

    【讨论】:

    • 你是否有一个 github 存储库的链接,该存储库包含与 Rocket 和 wasm 一起使用的完整代码以及书中的示例?
    【解决方案2】:

    跟进 Ben 的回答。 .wasm 文件与application/javascript mime 一起发送,因此浏览器正试图将其作为javascript 执行。要使用application/wasm mime 发送它,请确保您的回复是Option<rocket::response::NamedFile> 类型。

    这是一个例子:

    #[get("/pkg/<file..>")]
    fn get_pkg(file : PathBuf) -> Option<rocket::response::NamedFile> {
       NamedFile::open(Path::new("client/pkg/").join(file)).ok()
    }
    

    关于第二个问题 - 事实证明,与其手动编辑 wasm-pack build 生成的 javascript,您实际上可以要求 wasm-pack 生成可以在浏览器中运行并加载您的 wasm 的 javascript。简单地做 wasm-pack build --target web.

    剩下要做的就是在你身边添加这样的东西:

    <script type="module">
      import init from './pkg/client.js'; //client.js is the file generated by wasm
      async function run() {
        await init();
      }
      run();
    </script>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-05-06
      • 2021-03-23
      • 2018-05-12
      • 1970-01-01
      • 2023-02-25
      • 2021-09-21
      • 2020-07-12
      相关资源
      最近更新 更多