Laravel与Nuxt配置CORS跨域失败:仍报Access-Control-Allow-Origin缺失错误
跨域问题排查与解决
错误信息
http://localhost:8000/sanctum/csrf-cookie从源http://localhost:3000发起的请求被CORS策略阻止:请求的资源上不存在Access-Control-Allow-Origin头。
当前配置
Nuxt Axios 配置
import axios from "axios" export default defineNuxtPlugin((NuxtApp) => { axios.defaults.withCredentials = true; axios.defaults.withXSRFToken = true; axios.defaults.baseURL = 'http://localhost:8000' return { provide: { axios: axios }, } })
Laravel CORS 配置
'paths' => [ 'api/*', '/login', '/register', '/logout', '/sanctum/csrf-cookie' ], 'allowed_methods' => ['*'], 'allowed_origins' => [env('FRONTEND_URL', 'http://localhost:3000')], 'allowed_origins_patterns' => [], 'allowed_headers' => ['*'], 'exposed_headers' => [], 'max_age' => 0, 'supports_credentials' => true, ];
尝试过的代理配置
代理中间件文件 server-middleware/api-proxy.js
const axios = require('axios'); module.exports = async function (req, res) { const { data, headers } = await axios({ baseURL: 'http://localhost:8000', url: req.url, method: req.method, headers: { ...req.headers, 'Access-Control-Allow-Origin': 'http://localhost:3000', 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE', 'Access-Control-Allow-Headers': 'Content-Type', }, data: req.body || null, }); Object.keys(headers).forEach((key) => { res.setHeader(key, headers[key]); }); res.end(JSON.stringify(data)); };
Nuxt 配置文件 nuxt.config.ts
serverMiddleware: [ { path: '/api', handler: '~/server-middleware/api-proxy.js', }, ],
问题
按上述配置后仍出现相同跨域错误,代理配置也未解决问题。
排查与解决步骤
1. 确保Laravel配置生效
- 检查
.env文件中FRONTEND_URL是否准确设置为http://localhost:3000,无多余斜杠或空格 - 执行
php artisan config:clear清除配置缓存,重启Laravel服务,避免旧配置残留
2. 修正Nuxt Axios配置
避免直接修改全局axios实例,改用独立实例:
import axios from "axios" export default defineNuxtPlugin(() => { const instance = axios.create({ baseURL: 'http://localhost:8000', withCredentials: true, withXSRFToken: true }) return { provide: { axios: instance } } })
如果使用Nuxt 3内置的useFetch/useAsyncData,需显式配置凭证:
const { data } = await useFetch('/sanctum/csrf-cookie', { baseURL: 'http://localhost:8000', credentials: 'include' })
3. 修复代理逻辑错误
当前代理的CORS头配置逻辑颠倒,正确写法如下(处理OPTIONS预检请求+转发响应):
const axios = require('axios'); module.exports = async function (req, res) { // 处理OPTIONS预检请求 if (req.method === 'OPTIONS') { res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000'); res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS'); res.setHeader('Access-Control-Allow-Headers', 'Content-Type, X-XSRF-TOKEN'); res.setHeader('Access-Control-Allow-Credentials', 'true'); return res.end(); } try { const { data, headers } = await axios({ baseURL: 'http://localhost:8000', url: req.url, method: req.method, headers: { ...req.headers, Origin: 'http://localhost:8000' // 伪装源避免Laravel CORS校验问题 }, data: req.body || null, withCredentials: true }); // 添加CORS响应头 res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000'); res.setHeader('Access-Control-Allow-Credentials', 'true'); // 转发Laravel其他响应头 Object.keys(headers).forEach(key => { if (!['Access-Control-Allow-Origin', 'Access-Control-Allow-Credentials'].includes(key)) { res.setHeader(key, headers[key]); } }); res.end(JSON.stringify(data)); } catch (err) { res.status(err.response?.status || 500).end(JSON.stringify(err.response?.data || { message: 'Proxy error' })); } };
同时修改前端请求路径为代理路径,比如将/sanctum/csrf-cookie改为/api/sanctum/csrf-cookie
4. 检查Sanctum状态域配置
打开config/sanctum.php,确保stateful包含前端域名:
'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf( '%s%s', 'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1', env('APP_URL') ? ','.parse_url(env('APP_URL'), PHP_URL_HOST) : '' ))),
执行php artisan config:clear使配置生效
5. 浏览器端验证
- 打开开发者工具Network标签,查看
csrf-cookie请求的Request Headers中Origin是否为http://localhost:3000 - 检查Response Headers是否存在
Access-Control-Allow-Origin和Access-Control-Allow-Credentials - 使用隐身模式测试,避免缓存影响
内容的提问来源于stack exchange,提问作者Adrian Cerush
相关产品推荐
相关产品推荐

