Laravel/Inertiajs项目Vite构建后CSP Nonce报错求助
Laravel 10 + Inertia + Ziggy 生产环境CSP Nonce导致链接导航被阻止的解决方法
问题核心
生产环境构建后,点击Inertia链接触发CSP阻止脚本,开发环境正常,已按官方配置@routes的nonce和对应中间件,禁用route() helper也无效。
具体解决步骤
1. 修正CSP头配置
确保CSP中间件的script-src指令包含'nonce-{YOUR_NONCE}'和'strict-dynamic'(允许可信脚本加载动态生成的脚本),同时保留'self'用于本地静态资源。示例配置:
return [ 'default-src' => ["'self'"], 'script-src' => ["'nonce-" . $nonce . "'", "'strict-dynamic'", "'self'"], 'style-src' => ["'self'", "'unsafe-inline'"], // Vue样式渲染可能需要该配置,或改用nonce处理样式 'img-src' => ["'self'", "data:", "https:"], 'font-src' => ["'self'"], ];
2. 手动控制Ziggy路由脚本的Nonce
替换@routes(nonce: ...)指令,手动生成Ziggy路由脚本并明确添加nonce,避免自动生成时的遗漏:
<script nonce="{{ Illuminate\Support\Facades\Vite::cspNonce() }}"> const Ziggy = @json($ziggy); window.Ziggy = Ziggy; </script>
3. 确认Vite构建脚本的Nonce属性
检查生产环境页面源码中Vite生成的脚本标签是否带有nonce属性。如果没有,手动渲染Vite入口脚本并添加nonce:
@foreach(Vite::getClientEntrypoints() as $entrypoint) <script nonce="{{ Vite::cspNonce() }}" type="module" src="{{ $entrypoint }}"></script> @endforeach @foreach(Vite::getEntrypoints(['resources/js/app.js', "resources/js/Pages/{$page['component']}.vue"]) as $entrypoint) <script nonce="{{ Vite::cspNonce() }}" type="module" src="{{ $entrypoint }}"></script> @endforeach
4. 检查Inertia初始化配置
确保resources/js/app.js中Inertia的组件解析逻辑符合CSP要求,比如使用静态导入而非动态导入(或依赖'strict-dynamic'允许动态加载):
import { createApp, h } from 'vue' import { createInertiaApp } from '@inertiajs/vue3' import { ZiggyVue } from '../../vendor/tightenco/ziggy/dist/vue.m' createInertiaApp({ resolve: name => { const pages = import.meta.glob('./Pages/**/*.vue', { eager: true }) return pages[`./Pages/${name}.vue`] }, setup({ el, App, props, plugin }) { createApp({ render: () => h(App, props) }) .use(plugin) .use(ZiggyVue) .mount(el) }, })
5. 清除缓存并重新构建
执行以下命令清除缓存,确保生产环境配置生效:
php artisan cache:clear php artisan config:clear npm run build
同时确认.env文件中APP_ENV=production、APP_DEBUG=false,避免调试模式干扰CSP规则。
内容的提问来源于stack exchange,提问作者LorenzoBerti
相关产品推荐
相关产品推荐

