【问题标题】:laravel - redirect to GET request after form is submittedlaravel - 提交表单后重定向到 GET 请求
【发布时间】:2021-09-17 10:35:10
【问题描述】:

我想提交一个带有 post 请求的表单,控制器中的方法将重定向到一个视图。

控制器:

//Create quotation
    public function quotation(Request $request){
        
        $validated = $request->validate([
            'parcel_weight' => 'required',
            'parcel_size' => 'required',
            'postcode_pickup' => 'required|postal_code:MY|exists:postcodes,postcode',
            'postcode_delivery' => 'required|postal_code:MY|exists:postcodes,postcode'
        ]);

        //logic to compute the quotation rate for each courier based on the inputs
        //dd($request->all());
        
        return redirect()->route('quotation.show');
       
    }

    //Show quotation
    public function showQuotation(){
        
        return view('orders.quotation');
    }

web.php:

//Create new order
Route::get('/dashboard/orders','Dashboard\OrderController@index')->name('order.index');

//Generate quotation
Route::post('/dashboard/orders','Dashboard\OrderController@quotation')->name('order.quotation');

//Quotation page
Route::get('/dashboard/orders/quotation','Dashboard\OrderController@showQuotation')->name('quotation.show');

此代码工作正常,但要点击route('quotation.show'),必须从表单提交数据。如果我只是复制 URI 并粘贴到浏览器 .../dashboard/orders/quotation 中,那么我仍然可以在不提交任何输入的情况下查看该页面。如何防止这种情况发生?

编辑:

使用with() 似乎不起作用。

//Create quotation
    public function quotation(Request $request){
        
        $validated = $request->validate([
            'parcel_weight' => 'required',
            'parcel_size' => 'required',
            'postcode_pickup' => 'required|postal_code:MY|exists:postcodes,postcode',
            'postcode_delivery' => 'required|postal_code:MY|exists:postcodes,postcode'
        ]);

        //logic to compute the quotation rate for each courier based on the inputs
        //dd($request->all());
        
        return redirect()->route('quotation.show')->with(['form','form']);
       
    }

    //Show quotation
    public function showQuotation(){
       
        if(request()->has('form')){
            dd('Data has been submitted');

        }else{

            dd('NO DATA');
        }

            

    }

【问题讨论】:

  • redirect()->route() 上使用->with(['something' => 'something']),并检查是否request()->has('something')。如果没有,请阻止该操作。
  • @TimLewis 有没有其他方法可以用辅助函数来完成这个?
  • 一般来说,GET 请求应该返回一个view()POST 请求应该返回一个redirect() 无论如何。如果您不想直接从插入的 URL 访问 GET 请求,则使用 ->with()POST 重定向,它设置了 session 变量将完成此操作,并且(据我所知)可以不容易被欺骗。
  • 不知何故我尝试使用->with(),但request()....无法检测到
  • @TimLewis 我更新了我的问题以显示代码的外观。即使我提交了表单,它仍然没有返回任何数据。

标签: php laravel


【解决方案1】:

如果您想阻止直接导航到 GET 请求(例如,通过在浏览器的 URL 栏中输入 URL),那么您需要添加一些后端逻辑来防止这种情况发生。一个快速的解决方案是在redirect() 上包含一个session 变量。这会将它包含在会话中一次,然后您可以在其中检查它并采取相应措施。

在您的 POST 方法的处理程序中:

return redirect()->route('quotation.show')->with(['submitted' => true]);

然后,在您的 GET 方法的处理程序中:

if (session()->has('submitted')) {
  return view(...);
} else {
  abort(403); // Unauthorized
  // or
  return redirect('/'); // Return home, etc
}

旁注:dd('Access')dd('No Access') 非常适合调试以查看您的方法是否有效。

编辑:->with() 执行“Flash”,这意味着 submitted 将仅可用于单个请求。如果您需要它在会话中保持更长时间(即便于刷新页面),请调整代码:

session()->put('submitted', true);
return redirect()->route('quotation.show');

您现在可以在被重定向后刷新页面,但您也可以离开,然后手动返回,仍然可以看到结果。这是一个给予和接受的解决方案。

【讨论】:

  • 谢谢。尽管此解决方案可能存在问题,但假设我提交了数据并进入下一页,意外刷新页面(意味着未提交表单)将引发中止页面。
  • 应该的; ->with() 执行“flash”,这意味着会话值form(或我的回答中的submitted)持续一个呼叫。刷新页面将是一个新的调用。如果您需要将其持续多次调用,请调整代码。我会更新我的答案来处理这个问题?
  • 酷。提交我的请求后,会话将一直存在,直到我关闭浏览器并重置,对吗?尽管出于设计选择,我应该保持会话还是保持之前的行为方式?
  • 基本上,是的。你可以将 Laravel 配置为在浏览器关闭时取消会话,或者它们会根据会话生命周期自然过期,或者如果你真的想要,你可以将它“永远”存储在会话中。如何处理这些问题由您自己选择,无论您需要什么!
  • 好的,1 秒,我会把它移到那里。
猜你喜欢
  • 2019-01-19
  • 1970-01-01
  • 2020-12-17
  • 1970-01-01
  • 1970-01-01
  • 2018-11-08
  • 2013-04-13
  • 1970-01-01
相关资源
最近更新 更多