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

如何在style和script src中添加nonce?通过Webpack适配严格CSP

如何在Angular CLI 1.6.3 + Angular 5.2.0中为script/style的src添加nonce以适配严格CSP规则

针对你当前的技术栈,要实现给外部引入的script和style标签添加nonce属性来满足严格的内容安全策略(CSP)要求,我们可以通过自定义Webpack配置结合模板改造来完成,具体步骤如下:

1. 暴露Webpack配置文件(可选,不想eject可看替代方案)

Angular CLI 1.6.3默认隐藏Webpack配置,你可以通过eject命令把配置文件导出到项目根目录:

ng eject

执行后会生成webpack.config.js,注意此操作不可逆,之后部分Angular CLI命令可能无法使用。

2. 生成并传递nonce到Webpack配置

在webpack.config.js顶部引入Node的crypto模块生成安全的随机nonce,然后将其传递给HtmlWebpackPlugin:

// 在文件顶部添加
const crypto = require('crypto');
// 生成16字节的base64格式nonce(安全度较高)
const nonce = crypto.randomBytes(16).toString('base64');

// 找到HtmlWebpackPlugin的配置项,修改为:
new HtmlWebpackPlugin({
  template: './src/index.ejs', // 后续会将html改为ejs模板
  inject: false, // 关闭自动注入,我们手动在模板中处理资源引入
  nonce: nonce,
  // 保留原有的filename、hash、chunks等配置项
})

3. 修改index.html为ejs模板,手动注入带nonce的资源

把src/index.html重命名为src/index.ejs,通过ejs语法循环生成带nonce属性的script和style标签:

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>你的应用名称</title>
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
  <!-- 生成带nonce的style标签 -->
  <% for (const cssPath of Object.values(htmlWebpackPlugin.files.css)) { %>
    <link href="<%= cssPath %>" rel="stylesheet" nonce="<%= htmlWebpackPlugin.options.nonce %>">
  <% } %>
</head>
<body>
  <app-root></app-root>
  <!-- 生成带nonce的script标签 -->
  <% for (const chunk of Object.values(htmlWebpackPlugin.files.chunks)) { %>
    <script src="<%= chunk.entry %>" nonce="<%= htmlWebpackPlugin.options.nonce %>"></script>
  <% } %>
</body>
</html>

4. 配置服务器端的CSP头部

最后要在你的服务器(如Nginx、Express等)设置Content-Security-Policy头部,允许带有该nonce的脚本和样式:

  • 如果是Express服务器,示例代码:
app.use((req, res, next) => {
  const nonce = crypto.randomBytes(16).toString('base64');
  // 注意:这里的nonce要和Webpack生成的保持一致,建议将Webpack生成的nonce传递到服务器端
  res.setHeader(
    'Content-Security-Policy',
    `default-src 'self'; script-src 'nonce-${nonce}'; style-src 'nonce-${nonce}';`
  );
  next();
});
  • 如果是Nginx,在配置中添加:
add_header Content-Security-Policy "default-src 'self'; script-src 'nonce-<你的nonce值>'; style-src 'nonce-<你的nonce值>';";

注意:动态生成nonce时,必须确保Webpack和服务器使用同一个nonce值,否则CSP会拦截资源加载。

不eject的替代方案(可选)

如果你不想执行ng eject,可以使用@angular-builders/custom-webpack(对应5.x版本,适配Angular 5)扩展Webpack配置:

  1. 安装依赖:
npm install @angular-builders/custom-webpack@5 --save-dev
  1. 修改.angular-cli.json,将defaults.build.builder改为:
"builder": "@angular-builders/custom-webpack:browser"

并添加自定义Webpack配置的路径:

"customWebpackConfig": {
  "path": "./webpack.custom.js"
}
  1. 创建webpack.custom.js,写入之前Webpack配置中关于nonce和HtmlWebpackPlugin的修改逻辑即可。

内容的提问来源于stack exchange,提问作者user3300741

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:34:57