laravel - 提交表单后重定向到 GET 请求

时间:2021-07-06 19:41:42

标签: php laravel

我想提交一个带有 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');
        }

            

    }

1 个答案:

答案 0 :(得分:1)

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

在您的 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');

您现在可以在重定向后刷新页面,但您也可以导航离开,然后手动返回并仍能看到结果。这是一个让步的解决方案。