Chrome扩展页面执行JS遇EvalError:unsafe-eval未被允许
Chrome扩展EvalError问题解决
问题描述
Chrome扩展在页面运行JavaScript时触发以下错误:
Uncaught EvalError: Refused to evaluate a string as JavaScript because 'unsafe-eval'
当前manifest.json的内容安全策略(CSP)配置:
"content_security_policy": { "extension_pages": "script-src 'self' 'wasm-unsafe-eval'; object-src 'self' 'wasm-unsafe-eval'" }
popup.js中的核心代码:
cde = "alert('hi');"; chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) { var tab = tabs[0]; if (tab) { chrome.scripting.executeScript({ target: { tabId: tab.id }, function: (cde) => { console.log(cde); eval(cde); }, args: [cde] }).then(() => { console.log('Script executed successfully.'); }).catch((error) => { console.error(error); }); } else { console.error('No active tab found.'); } });
控制台已打印cde内容为alert('hi');,但仍抛出错误:
alert('hi'); VM143:3 Uncaught EvalError: Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'self' 'wasm-unsafe-eval' 'inline-speculation-rules' http://localhost:* http://127.0.0.1:*".
核心原因
通过chrome.scripting.executeScript注入的代码运行在目标页面的环境中,而非扩展自身的extension_pages环境。你在manifest.json里配置的CSP只对扩展自身的页面(如popup、background)生效,对注入到目标页面的脚本没有约束力,真正限制你的是目标页面的CSP。
解决方案
方案1:避免使用eval(推荐)
直接将执行逻辑封装成函数,而非字符串形式传递,彻底绕开eval的限制:
// 定义要执行的逻辑函数 const showAlert = () => { alert('hi'); }; chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) { var tab = tabs[0]; if (tab) { chrome.scripting.executeScript({ target: { tabId: tab.id }, function: showAlert // 直接传入函数 }).then(() => { console.log('Script executed successfully.'); }).catch((error) => { console.error(error); }); } else { console.error('No active tab found.'); } });
如果需要动态参数,通过args传递即可:
const showAlert = (message) => { alert(message); }; chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) { var tab = tabs[0]; if (tab) { chrome.scripting.executeScript({ target: { tabId: tab.id }, function: showAlert, args: ['hi'] // 传递动态参数 }).then(() => { console.log('Script executed successfully.'); }).catch((error) => { console.error(error); }); } else { console.error('No active tab found.'); } });
方案2:动态代码字符串注入(不推荐)
如果必须使用字符串形式的代码,可通过创建<script>标签的方式绕过eval限制:
cde = "alert('hi');"; chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) { var tab = tabs[0]; if (tab) { chrome.scripting.executeScript({ target: { tabId: tab.id }, function: (codeStr) => { const script = document.createElement('script'); script.textContent = codeStr; document.head.appendChild(script); script.remove(); // 执行完成后移除标签 }, args: [cde] }).then(() => { console.log('Script executed successfully.'); }).catch((error) => { console.error(error); }); } else { console.error('No active tab found.'); } });
注意:该方法仍受目标页面CSP的script-src限制,如果目标页面禁止unsafe-inline,此方法也会失效。
内容的提问来源于stack exchange,提问作者Mark Tait
相关产品推荐
相关产品推荐

