如何满足对 wasm 的严格 mime 类型检查?

Posted

技术标签:

【中文标题】如何满足对 wasm 的严格 mime 类型检查?【英文标题】:How to satisfy strict mime type checking for wasm? 【发布时间】:2020-01-29 00:54:23 【问题描述】:

我有一个使用 emscripten 编译的 webassembly 模块。现在我正在尝试使用 expressjs 在网页中提供它。

我已经尝试关注this gist,通过 webpack 包含 webassembly,包括我发现的一个修改,因为这个 gist 有点老了。

webpack 看起来像这样:

const path = require('path');

module.exports = 
  optimization: 
    mangleWasmImports: false
  ,
  entry: './src/index.js',
  output: 
    path: path.resolve(__dirname, './dist/'),
    filename: 'dynamic-graph.bundle.js'
  ,
  target: "web",
  module: 
    rules: [
      // Emscripten JS files define a global. With `exports-loader` we can 
      // load these files correctly (provided the global’s name is the same
      // as the file name).
      
        test: /fourd\.js$/,
        loader: "exports-loader"
      ,
      // wasm files should not be processed but just be emitted and we want
      // to have their public URL.
      
        test: /fourd\.wasm$/,
        type: "javascript/auto",
        loader: "file-loader",
        options: 
          publicPath: "dist/"
        
      
    ]
  


我在开发服务器上设置了 https,因为我知道这有时会导致问题。这是一个自签名证书,但 Chrome 和 Firefox 让我绕过了这个问题。

const express = require('express')
const fs = require('fs')
express.static.mime.types['wasm'] = 'application/wasm'
const https = require('https')
const app = express()

app.use('/', express.static(__dirname))
app.use((req, res, next) => 
  res.header('X-Content-Type-Options', 'nosniff')
  next()
)
https.createServer(
  key: fs.readFileSync('server.key'),
  cert: fs.readFileSync('server.cert')
, app).listen(8000, () => 
  console.log('Listening...')
)

在之前的版本中,我可以使用 Module.onRuntimeInitialized 来等待 wasm 模块被实例化。该代码仍然有效,我使用与以前相同的 em++ 标志编译 webpack,即-std=c++11 -s WASM=1 -s ALLOW_MEMORY_GROWTH=1 -s SAFE_HEAP=1 -O0 -g4 -s ASSERTIONS=1

我在浏览器中遇到的错误如下:Failed to load module script: The server responded with a non-JavaScript MIME type of "application/wasm". Strict MIME type checking is enforced for module scripts per html spec. 这让我陷入了循环,因为我认为 application/wasm 正是 MIME 类型应该是的。

【问题讨论】:

我已经用 Apache、expressjs 和 python 的 simplehttpserver 试过这个。 【参考方案1】:

application/wasm 确实是用于 WASM 文件的正确 MIME 类型。问题是没有通过WebAssembly.instantiate[Streaming] 以正确的方式导入WASM。相反,它是通过以下方式导入的:

import  add  from "./add.wasm";

通常,这会被转译为 WebAssembly.instantiate 调用,但这不会发生。相反,该模块在没有 imports 被转换为正确导入的情况下被提供。确保您正在转换 JavaScript,而不仅仅是将其作为静态文件提供,就像该代码中的情况一样。或者,您可以自己拨打WebAssembly.instantiate

【讨论】:

以上是关于如何满足对 wasm 的严格 mime 类型检查?的主要内容,如果未能解决你的问题,请参考以下文章

拒绝执行脚本,因为 MIME 类型 ('text/html') 不可执行,并且启用了严格的 MIME 类型检查

拒绝执行脚本并启用严格的 MIME 类型检查

拒绝执行脚本,因为它的 MIME 类型 ('text/html') 不可执行,并且启用了严格的 MIME 类型检查

拒绝执行脚本,因为它的 MIME 类型 ('text/html') 不可执行并且启用了严格的 MIME 类型检查

禁用 Chrome 严格的 MIME 类型检查

拒绝从 '*' 执行脚本,因为它的 MIME 类型 ('application/json') 不可执行,并且启用了严格的 MIME 类型检查