HTTP 路由

2018-12-17 10:40 更新

基本路由

您將在 app/Http/routes.php 中定義應(yīng)用中的大多數(shù)路由,這個文件加載了 App\Providers\RouteServiceProvider 類。 大多數(shù)基本的 Laravel 路由都只接受一個 URI 和 一個 閉包(Closure) 參數(shù):

基本 GET 路由

Route::get('/', function(){
    return 'Hello World';});

           

其他基礎(chǔ)路由

Route::post('foo/bar', function(){
    return 'Hello World';});Route::put('foo/bar', function(){
    //});Route::delete('foo/bar', function(){
    //});

           

為多種請求注冊路由

Route::match(['get', 'post'], '/', function(){
    return 'Hello World';});

           

注冊路由響應(yīng)所有 HTTP 請求

Route::any('foo', function(){
    return 'Hello World';});

           

通常情況下,您將會需要為您的路由產(chǎn)生 URL,您可以使用 url 輔助函數(shù)來操作:

$url = url('foo');

           

           

CSRF 保護(hù)

Laravel 提供簡易的方法,讓您可以保護(hù)您的應(yīng)用程序不受到 CSRF (跨網(wǎng)站請求偽造) 攻擊??缇W(wǎng)站請求偽造是一種惡意的攻擊,借以代表經(jīng)過身份驗(yàn)證的用戶執(zhí)行未經(jīng)授權(quán)的命令。

Laravel 會自動在每一位用戶的 session 中放置隨機(jī)的 token ,這個 token 將被用來確保經(jīng)過驗(yàn)證的用戶是實(shí)際發(fā)出請求至應(yīng)用程序的用戶:

插入 CSRF Token 到表單

<input type="hidden" name="_token" value="<?php echo csrf_token(); ?>">

           

當(dāng)然也可以在 Blade 模板引擎使用:

<input type="hidden" name="_token" value="{{ csrf_token() }}">

           

您不需要手動驗(yàn)證在 POST、PUT、DELETE 請求的 CSRF token。 VerifyCsrfToken HTTP  中間件將保存在 session 中的請求輸入的 token 配對來驗(yàn)證 token 。

X-CSRF-TOKEN

除了尋找 CSRF token 作為「POST」參數(shù),中間件也檢查 X-XSRF-TOKEN 請求頭,比如,你可以把 token 存放在 meta 標(biāo)簽中, 然后使用 jQuery 將它加入到所有的請求頭中:

<meta name="csrf-token" content="{{ csrf_token() }}" />$.ajaxSetup({
    headers: {
        'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
    }});

           

現(xiàn)在所有的 AJAX 請求會自動加入 CSRF token:

$.ajax({
  url: "/foo/bar",})

           

X-XSRF-TOKEN

Laravel 也在 cookie 中存放了名為 XSRF-TOKEN 的 CSRF token。你可以使用這個 cookie 值來設(shè)置 X-XSRF-TOKEN 請求頭。一些 Javascript 框架,比如 Angular ,會自動設(shè)置這個值。

注意: X-CSRF-TOKENX-XSRF-TOKEN 的不同點(diǎn)在于前者使用的是純文本而后者是一個加密的值,因?yàn)樵?Laravel 中 cookies 始終是被加密過的。如果你使用 csrf_token() 函數(shù)來作為 token 的值, 你需要設(shè)置 X-CSRF-TOKEN 請求頭。

           

方法欺騙

HTML 表單沒有支持 PUT 、PATCHDELETE 請求。所以當(dāng)定義 PUT 、PATCH 以及 DELETE 路由并在 HTML 表單中被調(diào)用的時候,您將需要添加隱藏 _method 字段在表單中。

發(fā)送的 _method 字段對應(yīng)的值會被當(dāng)做 HTTP 請求方法。舉例來說:

<form action="/foo/bar" method="POST">
    <input type="hidden" name="_method" value="PUT">
    <input type="hidden" name="_token" value="<?php echo csrf_token(); ?>"></form>

           

           

路由參數(shù)

當(dāng)然,您可以獲取請求路由的 URI 區(qū)段。

基礎(chǔ)路由參數(shù)

Route::get('user/{id}', function($id){
    return 'User '.$id;});

           

注意: 路由參數(shù)不能包含 - 字符。使用下劃線替代 (_)。

可選擇的路由參數(shù)

Route::get('user/{name?}', function($name = null){
    return $name;});

           

帶默認(rèn)值的路由參數(shù)

Route::get('user/{name?}', function($name = 'John'){
    return $name;});

           

使用正則表達(dá)式限制參數(shù)

Route::get('user/{name}', function($name){
    //})->where('name', '[A-Za-z]+');Route::get('user/{id}', function($id){
    //})->where('id', '[0-9]+');

           

使用條件限制數(shù)組

Route::get('user/{id}/{name}', function($id, $name){
    //})->where(['id' => '[0-9]+', 'name' => '[a-z]+']);

           

定義全局模式

如果你想讓特定路由參數(shù)總是遵詢特定的正則表達(dá)式,可以使用 pattern 方法。在 RouteServiceProviderboot 方法里定義模式:

$router->pattern('id', '[0-9]+');

           

定義模式之后,會作用在所有使用這個特定參數(shù)的路由上:

Route::get('user/{id}', function($id){
    // 只有 {id} 是數(shù)字才被調(diào)用。});

           

取得路由參數(shù)

如果需要在路由外部取得其參數(shù),使用 input 方法:

if ($route->input('id') == 1){
    //}

           

你也可以使用 Illuminate\Http\Request 實(shí)體取得路由參數(shù)。當(dāng)前請求的實(shí)例可以通過 Request facade 取得,或透過類型提示 Illuminate\Http\Request 注入依賴:

use Illuminate\Http\Request;Route::get('user/{id}', function(Request $request, $id){
    if ($request->route('id'))
    {
        //    }});

           

           

命名路由

命名路由讓你更方便于產(chǎn)生 URL 與重定向特定路由。您可以用 as 的數(shù)組鍵值指定名稱給路由:

Route::get('user/profile', ['as' => 'profile', function(){
    //}]);

           

也可以為控制器動作指定路由名稱:

Route::get('user/profile', [
    'as' => 'profile', 'uses' => 'UserController@showProfile']);

           

現(xiàn)在你可以使用路由名稱產(chǎn)生 URL 或進(jìn)行重定向:

$url = route('profile');$redirect = redirect()->route('profile');

           

currentRouteName 方法會返回目前請求的路由名稱:

$name = Route::currentRouteName();

           

           

路由群組

有時候你的許多路由會有公用的需求,例如 URL 區(qū)段 (segments)、中間件、命名空間等等。你可以利用路由群組套用這些屬性到多個路由,而不用每個路由都設(shè)置一次。

將共享屬性作為一個數(shù)組當(dāng)做 Route::group 第一個參數(shù)。

           

Middleware

在群組共享屬性數(shù)組的 middleware 參數(shù)定義中間件列表,這些中間件就會應(yīng)用到群組內(nèi)的所有路由上。中間件將會按在列表內(nèi)指定的順序執(zhí)行:

Route::group(['middleware' => ['foo', 'bar']], function(){
    Route::get('/', function()
    {
        // Has Foo And Bar Middleware    });

    Route::get('user/profile', function()
    {
        // Has Foo And Bar Middleware    });});

           

           

Namespaces

您一樣可以在 group 屬性數(shù)組中使用 namespace 參數(shù),指定在這群組中控制器的命名空間:

Route::group(['namespace' => 'Admin'], function(){
    // Controllers Within The "App\Http\Controllers\Admin" Namespace
    Route::group(['namespace' => 'User'], function()
    {
        // Controllers Within The "App\Http\Controllers\Admin\User" Namespace    });});

           

注意: 在默認(rèn)情況下,RouteServiceProvider 包含內(nèi)置您命名空間群組的 routes.php 文件,讓您不須使用完整的 App\Http\Controllers 命名空間前綴就可以注冊控制器路由。

           

子域名路由

Laravel 路由一樣可以處理通配符的子域名,并且從域名中傳遞您的通配符參數(shù):

注冊子域名路由

Route::group(['domain' => '{account}.myapp.com'], function(){

    Route::get('user/{id}', function($account, $id)
    {
        //    });});

           

           

路由前綴

群組路由可以通過群組的描述數(shù)組中使用 prefix 選項(xiàng),將群組內(nèi)的路由加上前綴:

Route::group(['prefix' => 'admin'], function(){
    Route::get('users', function()
    {
        // Matches The "/admin/users" URL    });});

           

You can also utilize the prefix parameter to pass common parameters to your routes:

注冊一個 URL 參數(shù)到路由前綴

Route::group(['prefix' => 'accounts/{account_id}'], function(){
    Route::get('detail', function($account_id)
    {
        //    });});

           

你甚至可以在前綴中為已命名的參數(shù)定義限制:

Route::group([
    'prefix' => 'accounts/{account_id}',
    'where' => ['account_id' => '[0-9]+'],], function() {

    // Define Routes Here});

           

           

路由模型綁定

Laravel 模型綁定提供方便的方式將模型實(shí)體注入到您的路由中。例如,比起注入 User ID ,你可以選擇注入符合給定 ID 的 User 類實(shí)體。

首先,使用路由的 model 方法指定特定參數(shù)要對應(yīng)的類,您應(yīng)該在 RouteServiceProvider::boot 方法定義您的模型綁定:

綁定參數(shù)至模型

public function boot(Router $router){
    parent::boot($router);

    $router->model('user', 'App\User');}

           

然后定義一個有 {user} 參數(shù)的路由:

Route::get('profile/{user}', function(App\User $user){
    //});

           

因?yàn)槲覀円呀?jīng)將 {user} 參數(shù)綁定到 App\User 模型,所以 User 實(shí)體將被注入到路由。所以舉例來說,請求至 profile/1 將注入 ID 為 1 的 User 實(shí)體。

注意: 如果在數(shù)據(jù)庫中找不到匹配的模型實(shí)體,將引發(fā) 404 錯誤。

如果您想要自定「沒有找到」的行為,將閉包作為第三個參數(shù)傳入 model 方法:

Route::model('user', 'User', function(){
    throw new NotFoundHttpException;});

           

如果您想要使用您自己決定的邏輯,您應(yīng)該使用 Route::bind方法。閉包通過 bind 方法將傳遞 URI 區(qū)段數(shù)值,并應(yīng)該返回您想要被注入路由的類實(shí)體:

Route::bind('user', function($value){
    return User::where('name', $value)->first();});

           

           

拋出 404 錯誤

這里有兩種方法從路由手動觸發(fā) 404 錯誤。首先,您可以使用 abort 輔助函數(shù):

abort(404);

           

abort 輔助函數(shù)只是簡單拋出帶有特定狀態(tài)代碼的 Symfony\Component\HttpKernel\Exception\HttpException 。

第二,您可以手動拋出 Symfony\Component\HttpKernel\Exception\NotFoundHttpException 的實(shí)體。

有關(guān)如何處理 404 異常狀況和自定響應(yīng)的更多信息,可以參考錯誤章節(jié)內(nèi)的文檔。


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號