浏览器原生表单仅支持get和post,method="put"会被忽略而发post请求,导致laravel路由匹配失败;必须用@method('put')伪造方法并配合@csrf提供令牌,否则触发405或tokenmismatchexception。

为什么直接写 method="PUT" 不生效
浏览器原生表单只支持 GET 和 POST,写 method="PUT" 会被忽略,实际仍发 POST 请求。Laravel 路由匹配不到,返回 405 Method Not Allowed 或 404。
必须用 @method('PUT') 配合 @csrf
Laravel 的 Blade 指令会自动渲染隐藏字段,让服务端识别真实意图。这是最常用、最稳妥的做法:
生成的 HTML 实际是:
-
_method字段必须存在且值为PUT(大小写敏感) -
@csrf不可省略,否则触发TokenMismatchException - 表单
action必须指向 Laravel 中定义了PUT路由的 URL,例如Route::put('/users/{id}', ...)
不用 Blade?那就手动加 _method 隐藏字段
如果在非 Blade 环境(如纯 HTML、Vue 单文件组件内嵌表单),必须自己补上:
注意:
-
csrf_token()是 PHP 函数,仅在服务端渲染时可用;前端 JS 提交需提前从 meta 标签或 API 获取 token - 不要用
fetch或axios时还套这个表单结构——直接发原生PUT请求更干净 - 某些老版本 Laravel(App\Http\Kernel 中已启用
MethodOverride中间件(默认开启)
用 JavaScript 发 PUT 更灵活,但别漏掉 header
如果控制权在前端,推荐跳过表单模拟,直接用 fetch:
fetch('/users/123', {
method: 'PUT',
headers: {
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content'),
'Content-Type': 'application/json',
},
body: JSON.stringify({ name: 'Bob' })
});
关键点:
-
X-CSRF-TOKENheader 是 Laravel 默认校验方式,比传_token字段更符合 REST 风格 - 确保页面
里有<meta name="csrf-token" content="{{ csrf_token() }}"> - 后端控制器接收的是 JSON,要用
$request->json()->all()或直接类型提示Request $request自动解析
_method 告诉框架你想干什么,用 _token 或 X-CSRF-TOKEN 过掉验证。漏掉任意一个,请求就卡在中间件里。











