Next.js项目Content-Security-Policy配置未按预期生效如何解决
Next.js CSP配置失效问题修复方案
核心问题排查
你遇到的哪怕配置default-src *依然无法加载样式、字体的问题,本质是对CSP规则的覆盖范围存在认知偏差:
- CSP规则里的通配符
*不会自动放行内联脚本/样式、eval类动态代码,这两类资源必须显式配置'unsafe-inline'、'unsafe-eval'才会允许加载,而Next.js本身、你用的Chakra UI组件库都会注入内联样式,开发模式下的热更新功能还会用到eval执行代码,这部分没配置的话不管怎么放宽通配符都会被拦截。 - 你原有CSP规则漏了Google字体的完整域名:
@import拉取字体样式的域名是fonts.googleapis.com,实际加载字体二进制文件的域名是fonts.gstatic.com,两个都要加,缺一个字体就加载失败。 - 原有路由匹配规则没有覆盖Next.js内部静态资源路径、根路径public文件的响应,导致部分资源响应没带上正确的CSP头,规则不生效。
- 后续出现的Service Worker报错,是因为CSP默认的
default-src 'self'不会自动放行worker类资源,必须显式配置worker-src规则。 - 原有规则里写的
child-src example.com、style-src里的example.com属于无效配置,'self'已经覆盖同域资源,不需要重复加。
修正后的可直接落地配置
首先替换next.config.js里的CSP定义部分,区分开发/生产环境规则,避免开发环境热更新失效:
const isDev = process.env.NODE_ENV === 'development' // 按需求定制CSP规则 const ContentSecurityPolicy = ` default-src 'self'; script-src 'self' ${isDev ? "'unsafe-eval' 'unsafe-inline'" : ""}; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob:; font-src 'self' https://fonts.gstatic.com data:; connect-src 'self' ${isDev ? "webpack://*" : ""}; worker-src 'self'; child-src 'self'; frame-ancestors 'none'; ` // 其他原有安全头保持不变即可 const securityHeaders = [ { key: "X-Frame-Options", value: "deny" }, { key: "X-Content-Type-Options", value: "nosniff" }, { key: "Referrer-Policy", value: "strict-origin" }, { key: "Strict-Transport-Security", value: "max-age=31536000; includeSubDomains; preload" }, { key: "X-XSS-Protection", value: "1; mode=block", }, { key: "Permissions-Policy", value: "camera=(self); battery=(); geolocation=(); microphone=()" }, { key: 'Content-Security-Policy', value: ContentSecurityPolicy.replace(/\s{2,}/g, ' ').trim() } ]; /** @type {import('next').NextConfig} */ const nextConfig = { reactStrictMode: true, async headers() { return [ { // 匹配所有页面路由 source: "/:path((?!_next/|_static/|_vercel|[\\w-]+\\.\\w+).*)", headers: securityHeaders, }, { // 匹配所有静态资源、public文件夹文件、Next.js内部资源 source: "/(.*)", headers: securityHeaders, } ] }, } module.exports = nextConfig
规则说明
style-src加'unsafe-inline'是必要配置:Next.js、Chakra UI都会注入运行时内联样式,样式类的内联放行安全风险极低,个人项目不需要为了严格度牺牲可用性,如果是高安全要求的项目可以后续换成nonce方案收紧。img-src 'self'自动覆盖public文件夹下的所有图片资源,你代码里引用的/logo.jpeg不需要额外配置即可正常加载,额外加的data:、blob:是为了兼容Next/Image组件的占位图、上传类资源的加载。worker-src 'self'会放行同域下的Service Worker脚本,直接解决PWA注册的报错问题。- 开发环境额外加的
'unsafe-eval'、webpack://*规则仅在本地开发时生效,生产环境构建时会自动移除,不会带来线上安全风险。
生效验证
配置完成后必须重启Next.js服务(CSP配置修改后热更新不生效),打开Chrome DevTools做两项检查:
- 任意选一个请求看响应头,确认
Content-Security-Policy值和你配置的规则一致 - 看控制台CSP报错,确认样式、字体、logo、Service Worker都正常加载,无报错
注意:上线前必须跑一遍生产构建(
next build && next start)验证规则,不要只在开发环境测试就直接发布。
内容的提问来源于stack exchange,提问作者orc13a
相关产品推荐
相关产品推荐

