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

如何用Webpack 5为HtmlWebpackPlugin注入的script标签添加nonce属性及Thymeleaf注入nonce值

为HtmlWebpackPlugin生成的script标签添加nonce,并在Thymeleaf中注入动态nonce

一、Webpack 5 + HtmlWebpackPlugin添加nonce属性

根据你的场景需求,有两种实用方案可选:

方案1:配置固定nonce(测试或静态场景)

直接在webpack.config.js中通过HtmlWebpackPlugin的全局配置,为所有注入的script标签添加nonce属性:

const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  // ...其他Webpack配置项
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html',
      filename: 'index.html',
      script: {
        attributes: {
          nonce: 'your-static-nonce-value'
        }
      }
    })
  ]
};

方案2:自定义模板预留动态nonce占位符(适配Thymeleaf场景)

如果后续要让Thymeleaf接管nonce注入,建议在构建阶段生成带Thymeleaf表达式的模板:

  1. 创建自定义模板文件(如src/index.template.html),手动处理脚本引入并添加nonce占位符:
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>My SPA</title>
</head>
<body>
  <div id="app"></div>
  <!-- 遍历Webpack生成的脚本chunk,添加Thymeleaf兼容的nonce占位符 -->
  <% for (const chunk of htmlWebpackPlugin.files.js) { %>
    <script src="<%= chunk %>" nonce="[[${nonce}]]"></script>
  <% } %>
</body>
</html>
  1. 在webpack.config.js中配置使用该模板,并关闭自动注入:
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  // ...其他配置项
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.template.html',
      filename: 'index.html',
      inject: false // 关闭自动注入,使用模板中的手动引入逻辑
    })
  ]
};

构建完成后,HTML中的nonce会保留Thymeleaf表达式,方便后端动态替换。

二、Thymeleaf模板注入动态nonce值

将构建好的HTML作为Thymeleaf模板部署时,需要后端生成安全随机的nonce并传递给模板:

1. 后端代码示例(以Spring Boot为例)

在请求处理的Controller中生成符合CSP规范的随机nonce,并存入Model:

import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.security.SecureRandom;
import java.util.Base64;

@RestController
public class SpaController {

    @GetMapping("/")
    public String index(Model model) {
        // 生成16字节的安全随机nonce,转Base64编码
        SecureRandom secureRandom = new SecureRandom();
        byte[] nonceBytes = new byte[16];
        secureRandom.nextBytes(nonceBytes);
        String nonce = Base64.getEncoder().encodeToString(nonceBytes);
        
        // 将nonce传入Thymeleaf模板
        model.addAttribute("nonce", nonce);
        return "index"; // 对应构建好的index.html模板文件
    }
}

2. 配合CSP使用(推荐)

在模板的<head>中添加Content-Security-Policy meta标签,限制仅执行带对应nonce的脚本:

<meta http-equiv="Content-Security-Policy" content="script-src 'nonce-[[${nonce}]]';">

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 19:45:11