Laravel控制器store方法调用后跳转空白,如何后台执行不影响视图?
问题描述
我的视图里有多个fieldset,每个都包含一个提交按钮:
<button class="next action-button" type="submit" name="next" data-gotostep="3">(Save & Next)</button>
这些按钮调用的路由是:
Route::get('worksteps/store/{subprocess_id}', 'WorkstepsController@store')->name('worksteps.store');
store方法代码如下:
public function store(StoreWorkstepRequest $request) { $created_by_id = Auth::user()->id; $value = $request->target_value; $unit = $request->unit; $subprocess_id = $request->subprocess_id; $step_position = $request->subprocess_step_position; $step_system_id = $request->subprocess_system_id; $registry_date = Carbon::now()->toDateTimeString(); DB::table('subprocess_registry')->updateOrInsert( ['subprocess_id' => $step_system_id], ['value' => $value, 'unit' => $unit, 'step_position' => $step_position, 'created_at' => $registry_date, 'created_by_id' => $created_by_id, ] ); return back(); }
目前除了return back();会跳转到空白页之外,其他功能都正常。我需要调用store方法但不返回任何内容,也不改动当前视图。试过以下几种方式:
return back(); return redirect()->back(); return redirect()->previous();
这些都会跳转到空白页,也尝试过完全移除return语句,依旧不行。请问如何在后台调用store方法且不影响当前视图?
解决方案
核心问题是你用了同步表单提交,浏览器会强制刷新页面,不管控制器返回什么都无法保留当前视图。要实现后台静默调用,必须改成异步AJAX提交,具体步骤如下:
1. 前端修改:阻止默认提交,用AJAX发送请求
给表单添加提交事件监听,阻止默认刷新行为,用AJAX异步发送数据。以下是jQuery实现示例:
// 先确保页面引入jQuery,或者用原生JS实现 $(function() { // 给所有步骤表单绑定提交事件(假设表单有统一class:step-form) $('.step-form').on('submit', function(e) { e.preventDefault(); // 阻止默认表单提交刷新 const $form = $(this); const formData = $form.serialize(); const actionUrl = $form.attr('action'); const targetStep = $form.find('[data-gotostep]').data('gotostep'); // 发送AJAX请求 $.ajax({ url: actionUrl, method: 'GET', // 与你的路由方法保持一致,建议后续改成POST data: formData, success: function() { // 请求成功后,执行你需要的视图操作,比如切换到下一个fieldset $form.closest('fieldset').hide(); $(`fieldset[data-step="${targetStep}"]`).show(); }, error: function() { // 错误提示,根据需求调整 alert('保存失败,请重试'); } }); }); });
2. 后端调整:返回AJAX响应而非跳转
不需要返回页面跳转,直接给前端返回成功状态的JSON响应即可:
public function store(StoreWorkstepRequest $request) { // 原有存储逻辑完全保留 $created_by_id = Auth::user()->id; $value = $request->target_value; $unit = $request->unit; $subprocess_id = $request->subprocess_id; $step_position = $request->subprocess_step_position; $step_system_id = $request->subprocess_system_id; $registry_date = Carbon::now()->toDateTimeString(); DB::table('subprocess_registry')->updateOrInsert( ['subprocess_id' => $step_system_id], ['value' => $value, 'unit' => $unit, 'step_position' => $step_position, 'created_at' => $registry_date, 'created_by_id' => $created_by_id, ] ); // 返回JSON成功响应 return response()->json(['status' => 'success'], 200); }
3. 优化建议(可选但推荐)
从REST规范来说,创建/更新数据应该用POST而非GET,可以调整路由和AJAX方法:
- 修改路由:
Route::post('worksteps/store/{subprocess_id}', 'WorkstepsController@store')->name('worksteps.store');
- 前端AJAX的
method改成POST,并确保带上Laravel的CSRF令牌:
在页面头部添加CSRF元标签:
<meta name="csrf-token" content="{{ csrf_token() }}">
然后在AJAX请求前设置全局headers:
$.ajaxSetup({ headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') } });
内容的提问来源于stack exchange,提问作者Jessica Kimble
相关产品推荐
相关产品推荐

