Laravel POST请求报500错误及CORS跨域问题求助
解决Laravel中POST请求的CORS与500错误问题
问题现象
向http://127.0.0.1:8004/api/ciudadano/sinup发送POST请求时,浏览器返回:
Access to XMLHttpRequest at 'http://127.0.0.1:8004/api/ciudadano/sinup' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
POST http://127.0.0.1:8004/api/ciudadano/sinup net::ERR_FAILED 500
同时GET请求http://127.0.0.1:8004/api/test可正常访问。
已尝试的配置
- 自定义CORS中间件:
<?php namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; class Cors { public function handle(Request $request, Closure $next) { $response = $next($request); $response->header("Access-Control-Allow-Origin","*"); $response->header("Access-Control-Allow-Credentials","true"); $response->header("Access-Control-Max-Age","600"); $response->header("Access-Control-Allow-Methods","POST, GET, OPTIONS, DELETE, PUT"); $response->header("Access-Control-Allow-Headers", "Content-Type, Accept, Authorization, X-Requested-With, Application"); return $response; } }
- Kernel全局中间件配置:
protected $middleware = [ // \App\Http\Middleware\TrustHosts::class, \App\Http\Middleware\Cors::class, \Illuminate\Http\Middleware\HandleCors::class, \App\Http\Middleware\TrustProxies::class, \App\Http\Middleware\PreventRequestsDuringMaintenance::class, \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class, \App\Http\Middleware\TrimStrings::class, \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class, ];
- 使用
fruitcake/laravel-cors包,已在Kernel中添加\Fruitcake\Cors\HandleCors::class - 路由配置(api.php):
Route::get ('/test', function (){ return ("Backend OK"); }); Route::post('/ciudadano/sinup', 'App\Http\Controllers\CiudadanoController@store');
- 控制器代码:
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; class CiudadanoController extends Controller { public function store(Request $request) { dd($request); $this->validate($request, [ 'cuil'=>'required', 'nombre'=>'required', 'apellido'=>'required', 'email'=>'required', 'password'=>'required', ]); $ciudadano = Ciudadano::create($request->all()); dd($ciudadano); $ciudadano->save(); return ("OK"); } }
原因分析
控制器代码触发500错误:
- 未引入
Ciudadano模型,执行Ciudadano::create()时会抛出致命错误,返回500状态码 dd($request)会直接中断请求,后续验证、模型创建逻辑完全无法执行Ciudadano::create()已经完成数据持久化,后续的$ciudadano->save()属于冗余操作
- 未引入
CORS配置冲突且未处理预检请求:
- 同时启用自定义CORS中间件、Laravel自带
HandleCors和fruitcake的CORS中间件,三者规则冲突,导致CORS头无法正确设置 - 自定义中间件先执行业务逻辑再添加响应头,若业务逻辑报错(如500),响应头根本无法被添加,浏览器就会报CORS错误
- 同时启用自定义CORS中间件、Laravel自带
解决步骤
1. 修复控制器的500错误
- 在控制器顶部引入模型:
use App\Models\Ciudadano; // 根据实际模型路径调整
- 移除中断请求的
dd()语句,调整代码逻辑确保流程正常执行:
public function store(Request $request) { $this->validate($request, [ 'cuil'=>'required', 'nombre'=>'required', 'apellido'=>'required', 'email'=>'required', 'password'=>'required', ]); $ciudadano = Ciudadano::create($request->all()); // 可在此处添加生成token的逻辑 return response()->json(['message' => 'OK', 'data' => $ciudadano], 201); }
- 删除冗余的
$ciudadano->save()
2. 统一CORS配置(推荐使用fruitcake/laravel-cors)
- 删除自定义的
Cors中间件,同时从Kernel的$middleware数组中移除\App\Http\Middleware\Cors::class和\Illuminate\Http\Middleware\HandleCors::class - 确保Kernel全局中间件仅保留
\Fruitcake\Cors\HandleCors::class,且放在最前面:
protected $middleware = [ \Fruitcake\Cors\HandleCors::class, \App\Http\Middleware\TrustProxies::class, \App\Http\Middleware\PreventRequestsDuringMaintenance::class, \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class, \App\Http\Middleware\TrimStrings::class, \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class, ];
- 发布fruitcake的CORS配置文件:
php artisan vendor:publish --tag="cors"
- 编辑
config/cors.php,配置允许的源和方法:
return [ 'paths' => ['api/*'], 'allowed_methods' => ['*'], 'allowed_origins' => ['http://localhost:3000'], // 生产环境建议指定具体域名,不要用* 'allowed_origins_patterns' => [], 'allowed_headers' => ['*'], 'exposed_headers' => [], 'max_age' => 0, 'supports_credentials' => true, ];
3. 验证请求
重启Laravel服务后重新发送POST请求,此时500错误修复,CORS头可正确返回,请求即可正常完成。
内容的提问来源于stack exchange,提问作者Julián Oviedo
相关产品推荐
相关产品推荐

