Chrome扩展content.js中onnxruntime-web无法运行的问题
解决Chrome扩展Manifest V3中onnxruntime-web运行失败问题
核心问题分析
报错wasm streaming compile failed: TypeError: Failed to execute 'compile' on 'WebAssembly': HTTP status code is not ok通常由以下原因导致:
- 扩展资源访问权限配置不全
- 页面CSP(内容安全策略)禁止WebAssembly编译
- onnxruntime的Wasm资源路径映射错误
- Manifest V3对content script的环境限制
具体修复步骤
1. 修正Wasm资源路径映射与编译配置
onnxruntime-web依赖特定命名的Wasm文件,需确保路径映射准确,同时关闭流式编译避开CSP拦截:
import * as ort from "onnxruntime-web"; // 映射哈希后的Wasm文件到onnxruntime预期的文件名 ort.env.wasm.wasmPaths = { 'ort-wasm-simd-threaded.wasm': chrome.runtime.getURL('97d8ed7170daf34c90d5.wasm'), 'ort-wasm-simd-threaded.jsep.mjs': chrome.runtime.getURL('d04e26fffd0643b2519e.mjs'), }; // 关闭流式编译,避免部分页面CSP拦截 ort.env.wasm.streaming = false; const modelUrl = chrome.runtime.getURL('model.onnx'); let session; async function initModel() { session = await ort.InferenceSession.create(modelUrl, { executionProviders: ["wasm"], }); } // 用异步包裹避免顶层await的环境问题 (async () => { await initModel(); })();
2. 添加Manifest V3的CSP配置
在manifest.json中补充内容安全策略,允许WebAssembly编译所需的权限:
{ "manifest_version": 3, "name": "Demo Ext", "version": "1.0", "description": "Demo Ext", "permissions": ["storage", "tabs", "scripting"], // 新增CSP配置 "content_security_policy": { "extension_pages": "script-src 'self' 'unsafe-eval'; object-src 'self';", "content_scripts": "script-src 'self' 'unsafe-eval'; object-src 'self';" }, "content_scripts": [ { "matches": ["<all_urls>"], "js": ["content.js"] } ], "web_accessible_resources": [ { "resources": [ "97d8ed7170daf34c90d5.wasm", "d04e26fffd0643b2519e.mjs", "model.onnx", "model.onnx.data" ], "matches": ["<all_urls>"], // 启用动态URL适配哈希文件名 "use_dynamic_url": true } ] }
注:
unsafe-eval是编译Wasm的必需配置,onnxruntime会通过动态生成代码完成Wasm加载。
3. 优化Webpack打包配置
确保Webpack正确处理Wasm和模型文件,避免错误打包导致资源无法访问:
module.exports = { // ... 其他现有配置 module: { rules: [ // 处理Wasm文件 { test: /\.wasm$/, type: 'asset/resource', generator: { filename: '[hash][ext][query]' } }, // 处理ONNX模型及附属文件 { test: /\.(onnx|data)$/, type: 'asset/resource', generator: { filename: '[name][ext][query]' } } ] }, // 避免Webpack错误解析onnxruntime的内部模块 resolve: { alias: { 'onnxruntime-web': 'onnxruntime-web/dist/ort.min.js' } } };
4. 可选:将模型初始化移至Background Service Worker(推荐)
部分高安全级页面(如google.com)的CSP会严格限制content script的Wasm操作,可将模型逻辑移至background,通过消息通信调用:
1. 在manifest中注册background
"background": { "service_worker": "background.js" }
2. background.js中初始化模型并提供调用接口
import * as ort from "onnxruntime-web"; let session; async function initModel() { ort.env.wasm.wasmPaths = { 'ort-wasm-simd-threaded.wasm': chrome.runtime.getURL('97d8ed7170daf34c90d5.wasm'), 'ort-wasm-simd-threaded.jsep.mjs': chrome.runtime.getURL('d04e26fffd0643b2519e.mjs') }; ort.env.wasm.streaming = false; session = await ort.InferenceSession.create(chrome.runtime.getURL('model.onnx'), { executionProviders: ["wasm"] }); } initModel(); // 监听content script的推理请求 chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { if (message.type === 'runInference') { if (!session) { sendResponse({error: '模型未初始化完成'}); return; } session.run(message.inputs).then(results => sendResponse(results)); return true; // 标记异步响应 } });
3. content.ts中调用background的推理接口
// 移除原有的模型初始化代码 async function runInference(inputs) { return new Promise((resolve, reject) => { chrome.runtime.sendMessage({type: 'runInference', inputs}, (response) => { response.error ? reject(new Error(response.error)) : resolve(response); }); }); } // 使用示例: // runInference({input: ort.Tensor.create(...)}).then(res => console.log(res));
验证流程
- 重新打包扩展,确认dist目录包含所有资源文件
- 在Chrome中加载已解压的扩展,打开开发者工具查看控制台日志
- 在不同页面(包括google.com)测试模型初始化与推理功能
内容的提问来源于stack exchange,提问作者miran80
相关产品推荐
相关产品推荐

