You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 07:18:14