使用Axios调用Laravel API时PUT请求失效,如何排查解决?
PUT请求返回422错误,POST请求正常
问题代码
Vue组件请求代码
submit() { axios .put(`/api/posts/${this.slug}`, this.fields, { headers: { "content-type": "multipart/form-data" }, }) .then((res) => { // some logic }) .catch((error) => { // some logic }); }
Laravel路由代码
Route::group(['prefix' => 'posts', 'middleware' => 'auth:sanctum'], function () { Route::put('/{post:slug}', [PostController::class, 'update']); });
错误信息
xhr.js:220 PUT http://127.0.0.1:8000/api/posts/test-title-updated-33 422 (Unprocessable Content)
问题原因
Laravel对multipart/form-data类型的PUT/PATCH请求处理逻辑和POST不同:HTML原生表单不支持PUT方法,Laravel依赖表单里的_method字段来模拟PUT请求。但直接用axios发送PUT请求时,Laravel无法正确解析multipart格式的请求体,导致控制器接收不到提交的字段,触发验证失败,返回422错误。而POST请求的multipart数据会被Laravel正常解析,所以能正常工作。
解决方法
方法一:用POST请求模拟PUT(推荐)
把请求改成POST,同时在FormData里添加_method: 'PUT'字段,让Laravel识别为PUT请求:
submit() { // 创建FormData实例,处理multipart数据 const formData = new FormData(); // 遍历字段添加到FormData Object.keys(this.fields).forEach(key => { formData.append(key, this.fields[key]); }); // 添加_method字段,模拟PUT请求 formData.append('_method', 'PUT'); axios.post(`/api/posts/${this.slug}`, formData, { headers: { "content-type": "multipart/form-data" }, }) .then((res) => { // some logic }) .catch((error) => { // some logic }); }
方法二:调整Laravel中间件顺序(可选)
在App\Http\Kernel.php中,将\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class中间件移到api中间件组的\Illuminate\Routing\Middleware\SubstituteBindings::class之前,不过这种方法兼容性不如第一种,不推荐。
内容的提问来源于stack exchange,提问作者Alphy Gacheru
相关产品推荐
相关产品推荐

