Laravel POST路由被强制转为GET,表单提交提示页面过期求助
看起来你碰到了Laravel开发里两个很常见的小坑,我给你一步步拆解解决:
首先处理「页面过期+POST被转成GET」的问题
这个问题的核心是Laravel的CSRF保护机制。Laravel默认会对所有非GET的请求(比如POST、PUT)做CSRF验证,如果你没在表单里带上CSRF令牌,框架会直接判定请求非法,然后自动重定向成GET请求——这就是你看到URL变成http://127.0.0.1:8000/submit/$id的原因,同时抛出「Page has Expired」的提示。
解决方法超简单,只要在你的form标签内部加上@csrf指令就行:
<form method="POST" action="/submit/{{$id}}"> @csrf <!-- 就是这一行,Laravel会自动生成隐藏的CSRF令牌字段 --> <!-- 你的其他表单输入项 --> <button type="submit">提交</button> </form>
这个指令会帮你生成一个类似<input type="hidden" name="_token" value="你的CSRF令牌值">的隐藏字段,让Laravel认可你的POST请求。
然后解决「$id没有被解析成实际值」的问题
你看到URL里是字面量$id而不是实际的ID数字,大概率是以下两个原因之一:
你的视图文件不是Blade模板
Laravel只有.blade.php后缀的文件才会解析{{$id}}这种变量语法。如果你的文件是.php或者.html,框架只会把{{$id}}当成普通字符串输出。赶紧把视图文件的后缀改成.blade.php试试。你没有把$id变量传递给视图
假设你是从控制器返回这个表单视图,一定要确保把实际的ID变量传进去。比如:// 控制器里的代码示例 public function showForm() { $actualId = 123; // 这里是你要传递的实际ID值 return view('你的表单视图名称', ['id' => $actualId]); // 或者用compact简写:return view('你的表单视图名称', compact('actualId')); 注意这里变量名要和视图里的$id对应,或者改成['id' => $actualId] }
额外推荐:用路由命名+助手函数优化表单Action
为了避免硬编码URL,同时更稳妥地传递参数,建议给你的路由起个名字:
Route::post('/submit/{id}', function($id) { return 'Hello World'; })->name('submit.form'); // 给路由命名
然后表单的action可以用route()助手函数生成,这样即使以后路由URL变了,表单也不用改:
<form method="POST" action="{{ route('submit.form', ['id' => $id]) }}"> @csrf <!-- 其他表单内容 --> </form>
按上面的步骤来,应该就能解决你的问题了!
内容的提问来源于stack exchange,提问作者seamus

