Laravel fetch POST请求输入非空仍报必填错误 图片上传失效如何解决
问题根因
你第一版代码报全字段required错误的核心原因是请求头Content-Type和实际传输的body格式不匹配:
- 你给fetch请求手动设置了
Content-Type: application/json,但实际传入body的是FormData对象,对应的Content-Type应该是multipart/form-data - 就算你手动改成
multipart/form-data也不行,因为multipart请求需要包含分隔字段的边界符(boundary),这个值会由浏览器自动生成,手动指定Content-Type会覆盖掉带boundary的正确值,导致后端无法正常解析表单字段。
修复方案
1. 前端JS代码调整
直接删除fetch请求headers中的Content-Type配置即可,浏览器会自动识别body是FormData对象,生成正确的请求头。同时调整表单获取逻辑避免选择错误:
class AdForm { constructor() { this.form = $('form.adForm'); this.submitButton = $('button.adForm-submitBtn'); this.errorsElem = $('.adForm-errors'); this.successElem = $('.adForm-success'); this.submitAd(); } submitAd() { // 直接监听表单submit事件,比监听按钮点击更稳妥 this.form.on('submit', (e) => { e.preventDefault(); const actionUrl = this.form.attr('action'); const token = this.form.find('input[name="_token"]').val(); this.errorsElem.hide(); this.submitAdRequest(actionUrl, this.form, token); }); } async submitAdRequest(actionUrl, form, token) { try { const response = await fetch(actionUrl, { headers: { // 删掉Content-Type配置,让浏览器自动生成 'Accept': 'application/json', "X-CSRF-Token": token, "X-Requested-With": "XMLHttpRequest" }, method: "POST", credentials: "same-origin", body: new FormData(form[0]) }); const body = await response.json(); console.log(body); if (body.success) { this.successElem.show().text(body.message); } else { this.errorsElem.show().text(body.message); } } catch (error) { console.error(error); } } } const adForm = new AdForm();
2. 后端控制器调整
因为是AJAX请求,不要返回redirect跳转,统一返回JSON响应即可:
public function store(Request $request) { $validated = $request->validate([ 'title' => 'required', 'description' => 'required', 'condition' => 'required', 'county' => 'required', 'municipality' => 'required', 'address' => 'required', 'price' => 'required', 'images' => 'required', 'images.*' => 'max:2500', 'category' => 'required' ]); $allowedfileExtension = ['jpeg','jpg','png']; $files = []; if ($request->hasfile('images')) { $images = $request->file('images'); foreach ($images as $image) { $extension = $image->getClientOriginalExtension(); if (!in_array($extension, $allowedfileExtension)) { // 返回JSON格式错误 return response()->json([ 'success' => false, 'message' => 'Images must be png, jpeg or jpg!' ], 400); } $name = Str::random(30) . $image->getClientOriginalName(); $image->move(public_path().'/uploads/', $name); $files[] = $name; } } $validated['images'] = json_encode($files); $validated['user'] = Auth::user()->id; $validated['created_at'] = now(); $validated['updated_at'] = now(); Ads::insert($validated); // 返回成功响应 return response()->json([ 'success' => true, 'message' => 'Your ad has been created!' ]); }
3. 表单配置确认
确保你的表单文件上传字段配置正确:
<form class="adForm" action="{{ route('your.store.route') }}" method="POST" enctype="multipart/form-data"> @csrf <!-- 其他表单字段 --> <input type="file" name="images[]" multiple accept="image/jpeg,image/png"> <button type="submit" class="adForm-submitBtn">提交</button> </form>
调整后即可同时支持普通字段提交和多图片上传,不会再出现全字段required的错误。
内容的提问来源于stack exchange,提问作者Zain Shabir
相关产品推荐
相关产品推荐

