Laravel 5.5:登录后恢复中断的POST表单提交请求
解决Laravel 5.5中登录后恢复POST表单流程的方案
这个问题我之前在项目里也碰到过,Laravel 默认的 redirect()->intended() 确实只能处理 GET 请求,要恢复中断的 POST 提交流程,我们可以通过保存请求信息到 Session + 自动提交表单的方式来实现,下面是具体的步骤:
1. 创建自定义中间件,保存未登录的POST请求信息
首先,我们需要一个中间件来拦截那些需要登录但用户未登录的POST请求,把请求的URL、方法和表单数据暂存在Session里:
运行Artisan命令生成中间件:
php artisan make:middleware SavePostRequest
打开app/Http/Middleware/SavePostRequest.php,修改handle方法:
<?php namespace App\Http\Middleware; use Closure; use Illuminate\Support\Facades\Auth; class SavePostRequest { public function handle($request, Closure $next) { // 仅在用户未登录且为POST请求时保存数据 if (!Auth::check() && $request->isMethod('post')) { session()->flash('intended_post', [ 'url' => $request->fullUrl(), 'method' => $request->method(), 'data' => $request->all() ]); } return $next($request); } }
把这个中间件注册到app/Http/Kernel.php的web中间件组里(要放在Authenticate中间件之前执行):
protected $middlewareGroups = [ 'web' => [ // ...其他中间件 \App\Http\Middleware\SavePostRequest::class, \App\Http\Middleware\Authenticate::class, // ...其他中间件 ], ];
2. 修改登录控制器,处理保存的POST请求
打开app/Http/Controllers/Auth/LoginController.php,重写authenticated方法(这个方法会在用户登录成功后自动执行):
use Illuminate\Http\Request; protected function authenticated(Request $request, $user) { // 检查Session里是否有暂存的POST请求信息 if (session()->has('intended_post')) { $postData = session()->pull('intended_post'); // 返回自动提交的表单页面,恢复原POST请求 return response()->view('auth.resume_post', [ 'url' => $postData['url'], 'method' => $postData['method'], 'data' => $postData['data'] ]); } // 没有暂存请求的话,走默认的intended跳转逻辑 return redirect()->intended($this->redirectPath()); }
3. 创建自动提交的表单视图
在resources/views/auth目录下创建resume_post.blade.php视图,内容是一个自动提交的HTML表单:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>恢复请求...</title> <script> // 页面加载后自动提交表单 window.onload = function() { document.getElementById('resume-form').submit(); } </script> </head> <body> <form id="resume-form" action="{{ $url }}" method="{{ strtolower($method) }}"> @foreach($data as $key => $value) @if(is_array($value)) <!-- 处理数组类型的表单字段 --> @foreach($value as $subKey => $subValue) <input type="hidden" name="{{ $key }}[{{ $subKey }}]" value="{{ $subValue }}"> @endforeach @else <input type="hidden" name="{{ $key }}" value="{{ $value }}"> @endif @endforeach <p>正在恢复您的请求,请稍候...</p> </form> </body> </html>
4. 测试验证
现在当用户未登录时提交POST表单,会被重定向到登录页;登录成功后,系统会自动生成一个表单并提交到原来的POST URL,带上所有表单数据,完美恢复之前的提交流程。
补充说明
- 用
session()->flash()保存数据,确保数据仅在下次请求有效,避免Session残留过期数据 - 自动提交表单的方式符合HTTP规范(毕竟直接重定向无法改变请求方法),是这类场景下最合理的实现方案
- 如果表单包含文件上传,需要额外处理临时文件存储,普通表单数据都能完美适配
内容的提问来源于stack exchange,提问作者o15a3d4l11s2
相关产品推荐
相关产品推荐

