Laravel + React 项目中解决 CORS 跨域问题的完整指南

2次阅读

Laravel + React 项目中解决 CORS 跨域问题的完整指南

本文详解 laravel 后端如何正确配置 cors 策略,使 react 前端(运行在 http://localhost:3000)能安全调用 http://localhost:8000 的 api 接口,彻底解决 “no ‘access-control-allow-origin’ header” 错误。

本文详解 laravel 后端如何正确配置 cors 策略,使 react 前端(运行在 http://localhost:3000)能安全调用 http://localhost:8000 的 api 接口,彻底解决 “no ‘access-control-allow-origin’ header” 错误。

在 Laravel + React 全开发中,前端(如 create-react-app 运行于 http://localhost:3000)向 Laravel API(http://localhost:8000/api/…)发起请求时,浏览器会强制执行同源策略(Same-Origin Policy)。当请求携带认证头(如 Authorization: Bearer xxx)或使用非简单方法(如 PUT、delete),浏览器会先发送一个 预检请求(Preflight OPTIONS)。若后端未明确允许该来源、方法和头字段,就会抛出经典的 CORS 错误:

Access to XMLHttpRequest at 'http://localhost:8000/api/update_company'  from origin 'http://localhost:3000' has been blocked by CORS policy:  Response to preflight request doesn't pass access control check:  No 'Access-Control-Allow-Origin' header is present...

该错误并非前端代码缺陷,而是 Laravel 后端缺失跨域响应头所致。Laravel 官方推荐使用 fruitcake/laravel-cors 包(自 Laravel 9 起已内置集成),其配置入口为 config/cors.php。

✅ 正确配置 config/cors.php

请确保你的 config/cors.php 文件内容如下(关键项已加注释说明):

<?php  return [     /*      * 指定哪些 URL 路径启用 CORS —— 必须包含你的 API 路由前缀      * 注意:'api/*' 已覆盖所有 /api/xxx 接口;若使用 Sanctum CSRF,也需放行      */     'paths' => ['api/*', 'sanctum/csrf-cookie'],      /*      * 允许的 HTTP 方法列表 —— 前端使用了 PUT(axios.put),必须显式添加      */     'allowed_methods' => ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],      /*      * 允许的源(Origin)—— 生产环境严禁设为 '*',开发阶段可临时使用      * ✅ 推荐写法(明确指定前端地址):      */     'allowed_origins' => ['http://localhost:3000'],      /*      * 允许携带的请求头 —— 前端发送了 Authorization 头,必须放行      */     'allowed_headers' => ['*'], // 或更安全地指定:['Content-Type', 'X-Requested-With', 'Authorization']      /*      * 是否允许发送凭据(如 cookies、Authorization)—— 与 Sanctum 配合时必须设为 true      * ⚠️ 注意:若设置为 true,则 allowed_origins 不能为 '*',必须为具体域名      */     'supports_credentials' => true,      'exposed_headers' => [],     'max_age' => 3600, ];

? 关键要点

  • supports_credentials => true 是使用 Authorization: Bearer Token 的前提;
  • 一旦启用 supports_credentials,allowed_origins 必须指定具体协议+域名+端口(如 ‘http://localhost:3000’),不可用 ‘*’;
  • allowed_methods 必须包含 PUT(你 handleSubmit 中调用的是 axios.put);
  • paths 中的 ‘api/*’ 确保所有 API 路由(包括 /api/update_company)均受 CORS 控制。

? 同步检查 Sanctum 配置(避免二次拦截)

CORS 配置生效的前提是请求真正进入 Laravel 的 api 中间件。请确认 routes/api.php 中的路由已正确注册在 api 组内(你已做到),且 UpdateCompany 方法位于 auth:sanctum 中间件保护下(你也已做到)。

此外,请检查 config/sanctum.php 中的 stateful 域名是否包含前端地址:

'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS',      'localhost,localhost:3000,127.0.0.1,127.0.0.1:3000,::1' )),

✅ 建议在 .env 中显式声明(更清晰可控):

SANCTUM_STATEFUL_DOMAINS=localhost:3000,127.0.0.1:3000

? 验证与调试技巧

  1. 清除配置缓存(修改 cors.php 后必做):

    php artisan config:clear php artisan cache:clear
  2. 使用 curl 手动触发预检请求,验证响应头:

    curl -I -X OPTIONS    -H "Origin: http://localhost:3000"    -H "Access-Control-Request-Method: PUT"    -H "Access-Control-Request-Headers: Authorization"    http://localhost:8000/api/update_company

    ✅ 成功响应应包含:

    Access-Control-Allow-Origin: http://localhost:3000 Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE, OPTIONS Access-Control-Allow-Headers: Content-Type, X-Requested-With, Authorization Access-Control-Allow-Credentials: true
  3. 前端 axios 请求建议增强健壮性(可选优化):

    // 在 handleSubmit 中添加 baseURL 和超时,避免硬编码 const response = await axios.put(   'http://localhost:8000/api/update_company',   companyData,   {     headers: { Authorization: `Bearer ${token}` },     timeout: 10000,   } );

⚠️ 注意事项与最佳实践

  • *生产环境禁止 `allowed_origins: [‘‘]**:涉及认证凭据时,supports_credentials: true与’*’` 冲突,将导致 CORS 失败;
  • 不要在控制器中手动添加 CORS 头:绕过 cors 中间件会破坏一致性,且 Sanctum 的 token 验证可能失效;
  • php artisan serve 与 XAMPP 共存需谨慎:确保前端请求始终指向 http://localhost:8000(Laravel 开发服务器),而非 XAMPP 的 apache 端口;
  • React 中 localStorage.setItem(“company”, companyData) 有误:companyData 是对象,直接传入会转为 “[Object Object]” 字符串 —— 应改为 json.stringify(companyData)(已在你代码中体现,但需确认逻辑一致)。

完成上述配置后,重启 Laravel 服务(php artisan serve),刷新 React 页面并提交表单,CORS 错误将彻底消失,updateCompany 接口可正常接收并处理 PUT 请求。整个流程符合 Laravel 官方推荐的安全实践,兼顾开发效率与生产健壮性。

text=ZqhQzanResources