You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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请求体:

  1. 生成中间件:
php artisan make:middleware ParsePutFormData
  1. 编写中间件逻辑:
<?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);
    }
}
  1. 在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 02:15:14