在JavaScript / HTML中,Chrome报错Refused to execute inline script
客户端的浏览器chrome出现报错:Refused to execute inline script because it violates the following Content Security Policy directive: “script-src ‘self’”. Either the ‘unsafe-inline’ keyword, a hash (‘sha256-YnqnMlb3ecR4i/IOQz9KGjKWC2EPkS93mMFi3jtESOw=’), or a nonce (‘nonce-…’) is required to enable inline execution.
当浏览器提示 “Refused to execute inline script” 错误时,说明网页的 内容安全策略(Content Security Policy, CSP) 限制了内联脚本的执行。这是现代浏览器为防止跨站脚本攻击(XSS)而采取的安全措施。以下是详细解决方案:
1. 理解错误原因
错误核心信息:
Content Security Policy directive: "script-src 'self'"
-
含义:当前CSP策略仅允许加载同源(相同协议+域名+端口)的外部脚本文件(
<script src="...">
),但禁止执行内联脚本(直接写在HTML中的<script>...</script>
或事件属性如onclick="..."
)。 -
触发场景:若页面中包含以下代码会被拦截:
<!-- 内联脚本块 --> <script>alert("Hello"); </script><!-- 内联事件处理 --> <button onclick="handleClick()">Submit</button>
2. 解决方案
根据实际需求和安全要求,选择以下方法之一:
方案1:允许内联脚本(降低安全性,不推荐)
修改CSP策略,添加 unsafe-inline
关键字:
Content-Security-Policy: script-src 'self' 'unsafe-inline'
- 优点:快速修复,无需修改代码。
- 缺点:降低安全性,可能暴露XSS漏洞。
方案2:使用 Nonce(动态令牌)
通过为内联脚本添加唯一的 nonce
值,使CSP策略允许特定脚本执行。
-
服务器生成 Nonce(每次请求不同):
# Python示例(其他语言类似) import os nonce = os.urandom(16).hex()
-
在CSP头中声明 Nonce:
Content-Security-Policy: script-src 'self' 'nonce-{随机值}'
-
在HTML脚本标签中添加 Nonce:
<script nonce="这里是服务器生成的随机值">console.log("内联脚本已通过CSP验证"); </script>
方案3:使用 Hash(脚本内容哈希)
为内联脚本内容计算哈希值,并将哈希值添加到CSP策略。
-
计算脚本内容的SHA哈希:
# 示例:计算 "alert('Hello');" 的SHA-256哈希 echo -n "alert('Hello');" | openssl dgst -sha256 -binary | openssl base64 # 输出:YnqnMlb3ecR4i/IOQz9KGjKWC2EPkS93mMFi3jtESOw=
-
在CSP头中声明哈希值:
Content-Security-Policy: script-src 'self' 'sha256-YnqnMlb3ecR4i/IOQz9KGjKWC2EPkS93mMFi3jtESOw='
方案4:完全移除内联脚本(推荐)
将所有JavaScript代码移至外部文件,并通过 <script src="path/to/file.js">
引用。
-
重构前:
<script>// 内联代码 </script>
-
重构后:
<script src="/static/script.js"></script>
3. 根据服务器类型配置CSP
Nginx
在配置文件中添加HTTP头:
add_header Content-Security-Policy "script-src 'self' 'nonce-{动态值}'";
若使用动态生成Nonce,需配合后端语言(如PHP/Node.js)注入值。
Apache
在 .htaccess
或虚拟主机配置中添加:
Header set Content-Security-Policy "script-src 'self' 'sha256-...'"
Node.js(Express)
const express = require('express');
const app = express();
const crypto = require('crypto');app.use((req, res, next) => {const nonce = crypto.randomBytes(16).toString('base64');res.setHeader('Content-Security-Policy',`script-src 'self' 'nonce-${nonce}'`);res.locals.nonce = nonce; // 传递nonce到模板next();
});// 在模板引擎中注入nonce
app.get('/', (req, res) => {res.render('index', { nonce: res.locals.nonce });
});
4. 验证修复结果
- 打开浏览器开发者工具(F12),检查 Network 标签中的响应头是否包含更新后的CSP策略。
- 查看 Console 确认内联脚本错误已消失。
- 使用在线CSP验证工具(如 CSP Evaluator)检查策略安全性。
5. 高级CSP配置建议
若需更严格的策略,可扩展其他指令:
Content-Security-Policy: default-src 'self';script-src 'self' 'nonce-...';style-src 'self' 'unsafe-inline';img-src 'self' data:;connect-src 'self' https://api.example.com;frame-src 'none';object-src 'none';
default-src 'self'
: 默认所有资源仅允许同源。style-src 'unsafe-inline'
: 允许内联CSS(常见于框架)。frame-src 'none'
: 禁止嵌入iframe。
总结
方案 | 安全性 | 实现难度 | 适用场景 |
---|---|---|---|
允许unsafe-inline | 低 | 简单 | 临时测试或遗留系统 |
使用Nonce | 高 | 中等 | 动态生成页面的Web应用 |
使用Hash | 高 | 中等 | 静态内联脚本 |
移除内联脚本 | 最高 | 较高 | 新项目或重构代码 |
推荐优先级:移除内联脚本 > 使用Nonce > 使用Hash > 允许unsafe-inline
。