Laravel中AJAX提交FormData时Controller无法获取输入数据问题
问题根因
Controller拿不到表单值是两个配置/机制问题导致的:
- PHP原生仅会自动解析
POST请求的multipart/form-data格式请求体,你用PATCH方法提交FormData时,请求体不会被自动填充到$_POST,Laravel的$request对象自然拿不到对应字段。 - 你写的
dataType: false是无效配置,这个参数作用是声明你预期服务端返回的数据类型(比如json、html),传false既不会关闭数据解析,还可能引发意料外的响应处理问题,不需要的话直接删掉这行即可。
修复方案
二选一即可,优先用第一种,稳定性最高。
方案1:用Laravel方法伪造(推荐)
Laravel原生支持通过POST请求携带_method参数伪造HTTP方法,完美适配FormData提交场景,不需要改后端路由和控制器逻辑,只改前端代码:
$("#formCropUpdate").on("submit", function (event) { event.preventDefault(); var formId = $('#formId').val(); var url = '/Form/' + formId; var form = this; // 补变量声明,避免污染全局作用域 var formData = new FormData(form); // 新增:伪造PATCH方法 formData.append('_method', 'PATCH'); console.log(Array.from(formData)); $.ajax({ url: url, // 改为POST请求 type: "POST", headers: {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')}, cache: false, // 删除无效的dataType: false配置 contentType: false, processData: false, data:formData, success: function (response) { console.log(response); }, }); });
改完后Laravel会自动把请求路由到update方法,同时正常解析FormData里的所有普通字段、文件字段,不需要额外改后端代码。
方案2:保留PATCH请求,手动解析请求体
如果必须用原生PATCH方法提交,需要在后端手动解析multipart格式的原始请求体,这种方式处理文件上传逻辑繁琐,不推荐使用,参考实现如下:
public function update(Request $request){ $UserId = Auth::user()->id; $Company = Company::where('id', Auth::user()->company_id)->first(); // 手动解析PATCH请求的multipart内容 if ($request->isMethod('PATCH') && str_contains($request->header('Content-Type'), 'multipart/form-data')) { $rawInput = file_get_contents('php://input'); $boundary = substr($rawInput, 0, strpos($rawInput, "\r\n")); $parts = array_slice(explode($boundary, $rawInput), 1); $parsed = []; foreach ($parts as $part) { if ($part === "--\r\n") break; $part = ltrim($part, "\r\n"); [$headers, $body] = explode("\r\n\r\n", $part, 2); $body = substr($body, 0, -2); $disposition = []; foreach (explode("\r\n", $headers) as $header) { if (str_starts_with($header, 'Content-Disposition:')) { preg_match_all('/(?<= |;)([^ =]+)="([^"]+)"/', $header, $matches); $disposition = array_combine($matches[1], $matches[2]); } } if (isset($disposition['name'])) { $parsed[$disposition['name']] = $body; } } $request->merge($parsed); } return $request->all(); }
注意:如果表单里包含数组字段、文件上传字段,方案2的解析逻辑还需要额外补充适配,日常开发直接用方案1即可。
内容的提问来源于stack exchange,提问作者cleopatez
相关产品推荐
相关产品推荐

