Laravel+Nginx全栈项目部署后CORS跨域请求被拦截问题求助
问题原因说明
你遇到的是典型的前后端分离跨域校验失败问题,配置Nginx后无效的核心原因通常是Laravel自身返回的响应头覆盖了Nginx配置的头,或者Nginx配置规则位置不对、存在参数冲突。
解决方案
第一步:优先配置Laravel原生CORS规则(推荐)
Laravel 7及以上版本自带官方CORS中间件,优先级高于Nginx配置,优先用这套方案更稳定:
- 打开
config/cors.php文件,修改核心配置项:return [ // 匹配所有api开头的路由 'paths' => ['api/*', 'sanctum/csrf-cookie'], // 允许的前端源,要带凭证时不能写*,直接填你的前端地址:['http://159.138.83.48'] 'allowed_origins' => ['*'], 'allowed_origins_patterns' => [], // 允许所有请求方法 'allowed_methods' => ['*'], // 允许所有请求头 'allowed_headers' => ['*'], 'exposed_headers' => [], // 预检请求缓存时间 'max_age' => 1728000, // 如果前端请求带Cookie/Authorization头,这里要设为true 'supports_credentials' => false, ]; - 打开
app/Http/Kernel.php,确认API中间件组第一个注册了CORS中间件:protected $middlewareGroups = [ 'api' => [ \Fruitcake\Cors\HandleCors::class, // 必须放在最顶部 // 其他中间件... ], ]; - 执行命令清除Laravel配置缓存:
php artisan config:cache
第二步:修正Nginx配置冲突
你原有Nginx配置存在两处核心问题:1. 全局配置*通配符和OPTIONS请求里的$http_origin冲突,带凭证时*通配符会直接触发跨域报错;2. 头配置只写在server块的话,匹配到PHP处理块后会失效。
修正后的配置参考:
server { listen 443 ssl; server_name devapi.trial.com.my; # 省略SSL证书、站点根目录等原有配置 location / { try_files $uri $uri/ /index.php?$query_string; # 处理OPTIONS预检请求 if ($request_method = OPTIONS) { add_header Access-Control-Allow-Origin "$http_origin" always; add_header Access-Control-Allow-Credentials 'true' always; add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept, Authorization" always; add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS, PUT, DELETE' always; add_header Access-Control-Max-Age 1728000; add_header Content-Type 'text/plain; charset=utf-8'; add_header Content-Length 0; return 204; } # 普通请求加跨域头 add_header Access-Control-Allow-Origin "$http_origin" always; add_header Access-Control-Allow-Credentials 'true' always; } # 如果你单独配置了PHP处理块,必须在这里也加一遍跨域头配置 location ~ \.php$ { # 省略原有fastcgi_pass等PHP配置 add_header Access-Control-Allow-Origin "$http_origin" always; add_header Access-Control-Allow-Credentials 'true' always; } }
- 配置完成后执行
nginx -t校验配置合法性,通过后执行systemctl reload nginx重载配置生效。
第三步:验证排查
- 用curl命令直接测试预检请求,确认返回头存在
Access-Control-Allow-Origin字段:curl -I -X OPTIONS -H "Origin: http://159.138.83.48" -H "Access-Control-Request-Method: POST" https://devapi.trial.com.my/api/v1/login - 浏览器测试时按
Ctrl+Shift+R强制刷新,避免缓存旧的响应头。 - 确认没有用CDN缓存响应头,或者CDN侧没有覆盖跨域相关配置。
内容的提问来源于stack exchange,提问作者Armand
相关产品推荐
相关产品推荐

