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

如何阻止Svelte构建生成内联脚本以避免CSP违规?

解决SvelteKit(Node适配器)+ Express Helmet的CSP内联脚本违规问题

你遇到的是SvelteKit预渲染页面生成的内联脚本触发Helmet内容安全策略限制的问题,以下是几种不用'unsafe-inline'的解决办法:

方案1:使用浏览器报错给出的哈希值

浏览器报错里已经给出了内联脚本的SHA-256哈希,直接把它加入Helmet的CSP配置即可:

import helmet from 'helmet';

app.use(
  helmet.contentSecurityPolicy({
    directives: {
      scriptSrc: [
        "'self'",
        "'sha256-owsofOMZa3ZfSXXALEDxpXu6L/jonHMy8m+0p2OoBQM='"
      ],
      // 保留其他原有指令
    },
  })
);

注意:这个哈希值和内联脚本内容绑定,一旦SvelteKit版本更新、代码变更导致内联脚本内容改变,哈希会失效,需要重新从浏览器报错里获取新的哈希。

方案2:使用Nonce(更安全的动态方案)

Nonce是每个请求唯一的随机值,比哈希更灵活,适合生产环境:

步骤1:Express后端生成并配置Nonce

import crypto from 'crypto';
import helmet from 'helmet';

// 每个请求生成唯一nonce
app.use((req, res, next) => {
  res.locals.nonce = crypto.randomBytes(16).toString('hex');
  next();
});

// 配置Helmet的CSP,引入nonce
app.use(
  helmet.contentSecurityPolicy({
    directives: {
      scriptSrc: [
        "'self'",
        (req, res) => `'nonce-${res.locals.nonce}'`
      ],
      // 其他指令保持不变
    },
  })
);

步骤2:修改SvelteKit根模板注入Nonce

在项目src目录下创建或修改app.html,给内联脚本添加nonce属性:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  %sveltekit.head%
</head>
<body>
  %sveltekit.body%
  <script nonce="%nonce%">%sveltekit.inlineScript%</script>
</body>
</html>

步骤3:传递Nonce到SvelteKit渲染上下文

在Express处理SvelteKit请求的代码中,把nonce传给模板:

import { handler } from './build/handler.js';

app.use((req, res) => {
  return handler(req, res, {
    locals: {
      nonce: res.locals.nonce
    }
  });
});

方案3:禁用客户端Hydration(纯静态页面适用)

如果你的预渲染页面不需要客户端交互(纯静态展示),可以直接禁用SvelteKit的Hydration功能,这样就不会生成内联脚本:

在根目录的+layout.ts中添加:

export const hydrate = false;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 22:55:10