Smarty模板向Laravel API发Ajax POST请求触发CORS跨域错误求助
问题根因
这个CORS报错的核心触发原因是前端代码配置错误:
- 你把仅用于服务端返回的CORS响应头
Access-Control-Allow-Methods写到了前端请求头里。Access-Control-Allow-*系列字段是服务端返回给浏览器做跨源校验用的,不属于浏览器默认允许的请求头白名单,会强制触发OPTIONS预检请求,而后端没有在预检响应里允许这个自定义头,直接被浏览器拦截。 - 额外的配置问题:
http://localhost和http://127.0.0.1:8000属于不同源(域名、端口均不一致),前端加crossDomain: true无法解决浏览器CORS校验,所有跨源规则必须由后端配置。另外你写的contentType: false、processData: false是文件上传场景用的配置,普通键值对传参不需要,反而会额外触发预检请求。你代码里的鉴权头拼写也有误,标准Bearer鉴权头字段是Authorization不是Authentication,后续会导致鉴权失败。
修复步骤
1. 修正前端Ajax代码
删掉多余的请求头和无意义的配置,修正路径和头字段拼写:
$('.user_role').on('click',function(){ var role_id_and_user_id = $(this).val(); var func = 'delete'; if ($(this).is(":checked")) { func = 'insert' } console.log(func); $('.loading').show(); // 注意补全接口路径前缀,和报错里的/api/v2.3保持一致,避免404 var urlRemote = "{/literal}{$LARAVEL_BASEURL}{literal}/api/v2.3/user/updateUserRoles"; $.ajax({ url: urlRemote, type: "POST", data: { 'event': func, 'role_id': role_id_and_user_id, }, cache: false, headers: { 'Authorization':"Bearer {/literal}{$smarty.session.laravel_token}{literal}", "Accept": "application/json" }, success: function(responseData, textStatus, jqXHR) { $('.loading').hide(); console.log(responseData); }, error: function(jqXHR, textStatus, errorThrown) { $('.loading').hide(); // 打印完整响应方便定位后端报错 console.log(jqXHR.responseJSON, errorThrown); } }) return; });
2. 配置Laravel端CORS规则
Laravel 8及以上版本自带官方CORS中间件,不需要自己手写头信息,直接修改配置即可:
- 打开
config/cors.php,调整参数匹配你的场景:
return [ 'paths' => ['api/*', 'sanctum/csrf-cookie'], 'allowed_methods' => ['*'], // 允许你的前端源地址,带鉴权头时不要写*,否则浏览器会拦截 'allowed_origins' => ['http://localhost'], 'allowed_origins_patterns' => [], 'allowed_headers' => ['*'], 'exposed_headers' => [], 'max_age' => 0, // 如果前端需要携带cookie才设为true,此时allowed_origins不能配置为通配符 'supports_credentials' => false, ];
- 打开
app/Http/Kernel.php,确认全局中间件数组里已经注册CORS中间件:
protected $middleware = [ // 其他全局中间件 \Illuminate\Http\Middleware\HandleCors::class, // 其他全局中间件 ];
- 执行命令清除配置和路由缓存,避免旧配置生效:
php artisan config:clear php artisan route:clear
3. 异常排查
如果修改后仍然报CORS错误,按顺序排查:
- 先用Postman直接请求接口,确认接口本身没有返回500、404、401错误。如果后端代码提前报错终止,CORS头不会被返回,浏览器会统一报CORS拦截,掩盖真实错误。
- 确认
/api前缀的路由都在routes/api.php里定义,属于api中间件组,不要把接口路由放到web中间件组里触发CSRF校验。 - 不要在Nginx/Apache服务层重复配置CORS头,和Laravel自带的CORS中间件冲突会导致头重复、规则不匹配。
内容的提问来源于stack exchange,提问作者Ahmed Ghaffar
相关产品推荐
相关产品推荐

