Laravel+Inertia+React更新图片时后端接收不到请求数据
问题解决:Laravel + Inertia + React 上传图片时后端接收不到数据
核心问题
导致后端接收空数组的原因有两个:
- JSON无法序列化File对象:Inertia默认用JSON格式发送请求,但File对象不能被JSON序列化,导致数据无法正常传递到后端。
- PUT请求上传文件的限制:浏览器原生不支持通过PUT请求上传
multipart/form-data格式的内容,Laravel需要通过POST请求配合_method=PUT参数来模拟PUT操作。
解决方案
1. 前端修改:用FormData包装数据并模拟PUT请求
将handleSubmit函数改为使用FormData构建请求体,同时通过POST方法模拟PUT:
const handleSubmit = () => { const formData = new FormData(); // 添加普通表单字段 formData.append('title', title); formData.append('description', description); formData.append('category_id', category_id); formData.append('link_github', link_github); formData.append('link_behance', link_behance); formData.append('link_dribbble', link_dribbble); // 仅当用户选择了新图片时才添加该字段 if (img instanceof File) { formData.append('img', img); } // 向Laravel传递PUT请求标识 formData.append('_method', 'PUT'); router.post(`/admin/project/${props.project.id}`, formData, { headers: { 'Content-Type': 'multipart/form-data', }, }); }
2. 修正图片状态的处理逻辑
确保图片选择后的状态正确指向File对象(初始状态props.project.img是字符串路径,选择新图后变为File对象):
// 替换EditPage中UploadPhoto的onChange事件绑定 <UploadPhoto className="w-[500px]" onChange={(e) => setImg(e.target.files[0])}/>
3. 后端优化:添加验证与简化更新逻辑
给控制器添加数据验证,同时优化图片更新逻辑(可选删除旧图片):
use Illuminate\Support\Facades\Storage; public function update(Request $request, $id) { // 验证请求数据合法性 $validated = $request->validate([ 'title' => 'required|string|max:255', 'description' => 'required|string', 'category_id' => 'required|exists:categories,id', 'link_github' => 'nullable|url', 'link_behance' => 'nullable|url', 'link_dribbble' => 'nullable|url', 'img' => 'nullable|image|mimes:png,jpg,jpeg|max:2048', ]); $project = Project::findOrFail($id); // 若上传了新图片,删除旧图片并存储新文件 if ($request->hasFile('img')) { if ($project->img) { Storage::delete($project->img); } $validated['img'] = $request->file('img')->store('public/img'); } $project->update($validated); return redirect()->route('project.index')->with('success', 'Project berhasil dirubah!'); }
额外注意事项
- 确保你的Laravel路由配置为
Route::put或Route::resource生成的更新路由,这样才能匹配_method=PUT的模拟请求。 - 调试时可以在控制器中用
dd($request->all(), $request->file('img'))确认数据是否正常接收。
内容的提问来源于stack exchange,提问作者AKaGaMI
相关产品推荐
相关产品推荐

