Laravel中PUT类型Ajax请求数据无法正常解析的解决方案求助
Laravel中Ajax PUT请求参数解析异常的解决方案
问题背景
我有如下表单:
<form action="{{ route('admin.users.update', $user->id) }}" method="PUT" class="formajax_popup"> @csrf @method('PUT') <div class="form-group"> <label for="name">Name</label> <input type="text" name="name" value="{{ $user->name }}" class="form-control"> </div> <!-- 其他表单字段 --> </form>
通过自定义JavaScript类将表单转为Ajax请求,保留PUT请求方法和参数值,但请求返回500错误,后端调用$request->all()时无法正常获取参数。路由使用Route::resource配置:
Route::resource('users', AdminUserController::class);
希望遵循HTTP标准保留PUT请求方法,不想改为POST,求除手动解析外的解决方案。
解决方案
方案1:用FormData发送PUT请求
将表单数据转为FormData对象发送,Laravel能正常解析multipart/form-data格式的PUT请求参数:
const form = document.querySelector('.formajax_popup'); const formData = new FormData(form); fetch(form.action, { method: 'PUT', headers: { 'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content }, body: formData });
这种方式无需修改后端代码,浏览器会自动处理请求头,$request->all()可直接获取参数。
方案2:自定义中间件解析PUT表单数据
创建中间件自动解析application/x-www-form-urlencoded格式的PUT请求体:
- 生成中间件:
php artisan make:middleware ParsePutFormData
- 编写中间件逻辑:
<?php namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; class ParsePutFormData { public function handle(Request $request, Closure $next) { if ($request->isMethod('PUT') && str_contains($request->header('Content-Type'), 'application/x-www-form-urlencoded')) { parse_str($request->getContent(), $formData); $request->merge($formData); } return $next($request); } }
- 在
app/Http/Kernel.php的web中间件组中添加该中间件(放在VerifyCsrfToken之后):
protected $middlewareGroups = [ 'web' => [ // 其他中间件... \App\Http\Middleware\VerifyCsrfToken::class, \App\Http\Middleware\ParsePutFormData::class, ], ];
之后发送application/x-www-form-urlencoded格式的PUT请求,$request->all()即可正常获取参数。
方案3:使用Laravel方法伪装(兼容原生PUT逻辑)
在JS中发送POST请求并携带_method=PUT参数,既符合Laravel默认处理逻辑,又能在前端保持PUT请求的代码逻辑:
const form = document.querySelector('.formajax_popup'); const formData = new FormData(form); formData.append('_method', 'PUT'); // 添加方法伪装参数 fetch(form.action, { method: 'POST', headers: { 'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content }, body: formData });
这种方式无需修改后端,是Laravel官方推荐的HTTP方法伪装方案,避免了原生PUT请求的兼容性问题。
问题原因
PHP默认仅解析POST请求的application/x-www-form-urlencoded和multipart/form-data数据到$_POST数组,PUT请求的请求体不会自动解析,而Laravel默认未处理这种场景,导致$request->all()无法获取参数。
内容的提问来源于stack exchange,提问作者DCYılmaz
相关产品推荐
相关产品推荐

