Skip to content

路由

基本路由

最基本的 Laravel 路由接受一个 URI 和一个闭包,提供了一种非常简单且富有表现力的方法来定义路由和行为,而无需复杂的路由配置文件:

php
use Illuminate\Support\Facades\Route;

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

默认路由文件

所有的 Laravel 路由都定义在你的路由文件中,这些文件位于 routes 目录下。这些文件会被你的应用程序的 App\Providers\RouteServiceProvider 自动加载。routes/web.php 文件定义了用于你的 Web 界面的路由。这些路由被分配到 web 中间件组中,提供了会话状态和 CSRF 保护等功能。routes/api.php 中的路由是无状态的,并被分配到 api 中间件组中。

对于大多数应用程序,你将从在 routes/web.php 文件中定义路由开始。可以通过在浏览器中输入定义的路由 URL 来访问 routes/web.php 中定义的路由。例如,你可以通过在浏览器中导航到 http://example.com/user 来访问以下路由:

php
use App\Http\Controllers\UserController;

Route::get('/user', [UserController::class, 'index']);

routes/api.php 文件中定义的路由被 RouteServiceProvider 嵌套在一个路由组中。在这个组中,/api URI 前缀会被自动应用,因此你不需要手动将其应用到文件中的每个路由。你可以通过修改 RouteServiceProvider 类来修改前缀和其他路由组选项。

可用的路由器方法

路由器允许你注册响应任何 HTTP 动词的路由:

php
Route::get($uri, $callback);
Route::post($uri, $callback);
Route::put($uri, $callback);
Route::patch($uri, $callback);
Route::delete($uri, $callback);
Route::options($uri, $callback);

有时你可能需要注册一个响应多个 HTTP 动词的路由。你可以使用 match 方法来实现这一点。或者,你甚至可以注册一个响应所有 HTTP 动词的路由,使用 any 方法:

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

Route::any('/', function () {
    //
});
lightbulb

当定义共享相同 URI 的多个路由时,使用 getpostputpatchdeleteoptions 方法的路由应在使用 anymatchredirect 方法的路由之前定义。这确保了传入的请求与正确的路由匹配。

依赖注入

你可以在路由的回调签名中类型提示任何所需的依赖项。声明的依赖项将由 Laravel 服务容器 自动解析并注入到回调中。例如,你可以类型提示 Illuminate\Http\Request 类,以便将当前的 HTTP 请求自动注入到路由回调中:

php
use Illuminate\Http\Request;

Route::get('/users', function (Request $request) {
    // ...
});

CSRF 保护

请记住,指向 web 路由文件中定义的 POSTPUTPATCHDELETE 路由的任何 HTML 表单都应包含 CSRF 令牌字段。否则,请求将被拒绝。你可以在 CSRF 文档 中阅读更多关于 CSRF 保护的信息:

php
<form method="POST" action="/profile">
    @csrf
    ...
</form>

重定向路由

如果你正在定义一个重定向到另一个 URI 的路由,你可以使用 Route::redirect 方法。此方法提供了一个方便的快捷方式,因此你不必为执行简单的重定向定义完整的路由或控制器:

php
Route::redirect('/here', '/there');

默认情况下,Route::redirect 返回一个 302 状态码。你可以使用可选的第三个参数自定义状态码:

php
Route::redirect('/here', '/there', 301);

或者,你可以使用 Route::permanentRedirect 方法返回一个 301 状态码:

php
Route::permanentRedirect('/here', '/there');
exclamation

在重定向路由中使用路由参数时,以下参数由 Laravel 保留,不能使用:destinationstatus

视图路由

如果你的路由只需要返回一个 视图,你可以使用 Route::view 方法。与 redirect 方法一样,此方法提供了一个简单的快捷方式,因此你不必定义完整的路由或控制器。view 方法接受一个 URI 作为第一个参数和一个视图名称作为第二个参数。此外,你可以提供一个数组作为可选的第三个参数,以传递数据到视图:

php
Route::view('/welcome', 'welcome');

Route::view('/welcome', 'welcome', ['name' => 'Taylor']);
exclamation

在视图路由中使用路由参数时,以下参数由 Laravel 保留,不能使用:viewdatastatusheaders

路由列表

route:list Artisan 命令可以轻松提供应用程序定义的所有路由的概览:

shell
php artisan route:list

默认情况下,分配给每个路由的路由中间件不会显示在 route:list 输出中;但是,你可以通过在命令中添加 -v 选项来指示 Laravel 显示路由中间件:

shell
php artisan route:list -v

你还可以指示 Laravel 仅显示以给定 URI 开头的路由:

shell
php artisan route:list --path=api

此外,你可以通过在执行 route:list 命令时提供 --except-vendor 选项来指示 Laravel 隐藏由第三方包定义的任何路由:

shell
php artisan route:list --except-vendor

同样,你也可以通过在执行 route:list 命令时提供 --only-vendor 选项来指示 Laravel 仅显示由第三方包定义的路由:

shell
php artisan route:list --only-vendor

路由参数

必需参数

有时你需要在路由中捕获 URI 的片段。例如,你可能需要从 URL 中捕获用户的 ID。你可以通过定义路由参数来实现:

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

你可以根据路由的需要定义任意数量的路由参数:

php
Route::get('/posts/{post}/comments/{comment}', function ($postId, $commentId) {
    //
});

路由参数始终用 {} 括起来,并且应由字母字符组成。下划线 (_) 也可以在路由参数名称中使用。路由参数根据它们的顺序注入到路由回调/控制器中 - 路由回调/控制器参数的名称无关紧要。

参数和依赖注入

如果你的路由有依赖项,并希望 Laravel 服务容器自动注入到路由的回调中,你应该在依赖项之后列出路由参数:

php
use Illuminate\Http\Request;

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

可选参数

有时你可能需要指定一个可能并不总是出现在 URI 中的路由参数。你可以通过在参数名称后面加上 ? 来实现。确保为路由的相应变量提供一个默认值:

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

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

正则表达式约束

你可以使用路由实例上的 where 方法约束路由参数的格式。where 方法接受参数的名称和定义参数应如何约束的正则表达式:

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

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

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

为了方便起见,一些常用的正则表达式模式有帮助方法,允许你快速将模式约束添加到路由中:

php
Route::get('/user/{id}/{name}', function ($id, $name) {
    //
})->whereNumber('id')->whereAlpha('name');

Route::get('/user/{name}', function ($name) {
    //
})->whereAlphaNumeric('name');

Route::get('/user/{id}', function ($id) {
    //
})->whereUuid('id');

Route::get('/user/{id}', function ($id) {
    //
})->whereUlid('id');

Route::get('/category/{category}', function ($category) {
    //
})->whereIn('category', ['movie', 'song', 'painting']);

如果传入的请求不匹配路由模式约束,将返回 404 HTTP 响应。

全局约束

如果你希望路由参数始终被给定的正则表达式约束,你可以使用 pattern 方法。你应该在 App\Providers\RouteServiceProvider 类的 boot 方法中定义这些模式:

php
/**
 * 定义你的路由模型绑定、模式过滤器等。
 *
 * @return void
 */
public function boot()
{
    Route::pattern('id', '[0-9]+');
}

一旦定义了模式,它将自动应用于使用该参数名称的所有路由:

php
Route::get('/user/{id}', function ($id) {
    // 仅在 {id} 为数字时执行...
});

编码的正斜杠

Laravel 路由组件允许除 / 之外的所有字符出现在路由参数值中。你必须显式允许 / 成为占位符的一部分,使用 where 条件正则表达式:

php
Route::get('/search/{search}', function ($search) {
    return $search;
})->where('search', '.*');
exclamation

编码的正斜杠仅支持在最后一个路由段中。

命名路由

命名路由允许方便地为特定路由生成 URL 或重定向。你可以通过在路由定义上链接 name 方法来指定路由的名称:

php
Route::get('/user/profile', function () {
    //
})->name('profile');

你还可以为控制器操作指定路由名称:

php
Route::get(
    '/user/profile',
    [UserProfileController::class, 'show']
)->name('profile');
exclamation

路由名称应始终是唯一的。

生成命名路由的 URL

一旦为给定路由分配了名称,你可以在通过 Laravel 的 routeredirect 辅助函数生成 URL 或重定向时使用路由的名称:

php
// 生成 URL...
$url = route('profile');

// 生成重定向...
return redirect()->route('profile');

return to_route('profile');

如果命名路由定义了参数,你可以将参数作为 route 函数的第二个参数传递。给定的参数将自动插入到生成的 URL 中的正确位置:

php
Route::get('/user/{id}/profile', function ($id) {
    //
})->name('profile');

$url = route('profile', ['id' => 1]);

如果你在数组中传递了额外的参数,这些键/值对将自动添加到生成的 URL 的查询字符串中:

php
Route::get('/user/{id}/profile', function ($id) {
    //
})->name('profile');

$url = route('profile', ['id' => 1, 'photos' => 'yes']);

// /user/1/profile?photos=yes
lightbulb

有时,你可能希望为 URL 参数指定请求范围的默认值,例如当前语言环境。为此,你可以使用 URL::defaults 方法

检查当前路由

如果你想确定当前请求是否被路由到给定的命名路由,你可以在 Route 实例上使用 named 方法。例如,你可以从路由中间件中检查当前路由名称:

php
/**
 * 处理传入的请求。
 *
 * @param  \Illuminate\Http\Request  $request
 * @param  \Closure  $next
 * @return mixed
 */
public function handle($request, Closure $next)
{
    if ($request->route()->named('profile')) {
        //
    }

    return $next($request);
}

路由组

路由组允许你在大量路由中共享路由属性,例如中间件,而无需在每个单独的路由上定义这些属性。

嵌套组尝试智能地将属性与其父组“合并”。中间件和 where 条件被合并,而名称和前缀被附加。命名空间分隔符和 URI 前缀中的斜杠会在适当的地方自动添加。

中间件

要将 中间件 分配给组内的所有路由,你可以在定义组之前使用 middleware 方法。中间件按它们在数组中的顺序执行:

php
Route::middleware(['first', 'second'])->group(function () {
    Route::get('/', function () {
        // 使用第一个和第二个中间件...
    });

    Route::get('/user/profile', function () {
        // 使用第一个和第二个中间件...
    });
});

控制器

如果一组路由都使用相同的 控制器,你可以使用 controller 方法为组内的所有路由定义公共控制器。然后,在定义路由时,你只需提供它们调用的控制器方法:

php
use App\Http\Controllers\OrderController;

Route::controller(OrderController::class)->group(function () {
    Route::get('/orders/{id}', 'show');
    Route::post('/orders', 'store');
});

子域路由

路由组也可以用于处理子域路由。子域可以像路由 URI 一样分配路由参数,允许你捕获子域的一部分以在路由或控制器中使用。可以通过在定义组之前调用 domain 方法来指定子域:

php
Route::domain('{account}.example.com')->group(function () {
    Route::get('user/{id}', function ($account, $id) {
        //
    });
});
exclamation

为了确保你的子域路由可访问,你应该在注册根域路由之前注册子域路由。这将防止具有相同 URI 路径的根域路由覆盖子域路由。

路由前缀

prefix 方法可用于为组中的每个路由添加给定的 URI 前缀。例如,你可能希望为组内的所有路由 URI 添加 admin 前缀:

php
Route::prefix('admin')->group(function () {
    Route::get('/users', function () {
        // 匹配 "/admin/users" URL
    });
});

路由名称前缀

name 方法可用于为组中的每个路由名称添加给定的字符串前缀。例如,你可能希望为组内的所有路由名称添加 admin 前缀。给定的字符串会按指定的方式添加到路由名称前,因此我们将确保在前缀中提供尾随的 . 字符:

php
Route::name('admin.')->group(function () {
    Route::get('/users', function () {
        // 路由分配名称 "admin.users"...
    })->name('users');
});

路由模型绑定

在将模型 ID 注入到路由或控制器操作时,你通常会查询数据库以检索与该 ID 对应的模型。Laravel 路由模型绑定提供了一种方便的方法,可以将模型实例直接注入到你的路由中。例如,代替注入用户的 ID,你可以注入与给定 ID 匹配的整个 User 模型实例。

隐式绑定

Laravel 自动解析在路由或控制器操作中定义的 Eloquent 模型,其类型提示的变量名称与路由段名称匹配。例如:

php
use App\Models\User;

Route::get('/users/{user}', function (User $user) {
    return $user->email;
});

由于 $user 变量被类型提示为 App\Models\User Eloquent 模型,并且变量名称与 {user} URI 段匹配,Laravel 将自动注入与请求 URI 中相应值匹配的模型实例。如果在数据库中找不到匹配的模型实例,将自动生成 404 HTTP 响应。

当然,使用控制器方法时也可以进行隐式绑定。同样,请注意 {user} URI 段与控制器中的 $user 变量匹配,该变量包含 App\Models\User 类型提示:

php
use App\Http\Controllers\UserController;
use App\Models\User;

// 路由定义...
Route::get('/users/{user}', [UserController::class, 'show']);

// 控制器方法定义...
public function show(User $user)
{
    return view('user.profile', ['user' => $user]);
}

软删除模型

通常,隐式模型绑定不会检索已 软删除 的模型。但是,你可以通过在路由定义上链接 withTrashed 方法来指示隐式绑定检索这些模型:

php
use App\Models\User;

Route::get('/users/{user}', function (User $user) {
    return $user->email;
})->withTrashed();

自定义键

有时你可能希望使用 id 以外的列来解析 Eloquent 模型。为此,你可以在路由参数定义中指定列:

php
use App\Models\Post;

Route::get('/posts/{post:slug}', function (Post $post) {
    return $post;
});

如果你希望模型绑定在检索给定模型类时始终使用 id 以外的数据库列,你可以覆盖 Eloquent 模型上的 getRouteKeyName 方法:

php
/**
 * 获取模型的路由键。
 *
 * @return string
 */
public function getRouteKeyName()
{
    return 'slug';
}

自定义键和作用域

在单个路由定义中隐式绑定多个 Eloquent 模型时,你可能希望将第二个 Eloquent 模型的作用域设置为必须是前一个 Eloquent 模型的子级。例如,考虑这个路由定义,它为特定用户按 slug 检索博客文章:

php
use App\Models\Post;
use App\Models\User;

Route::get('/users/{user}/posts/{post:slug}', function (User $user, Post $post) {
    return $post;
});

在使用自定义键的隐式绑定作为嵌套路由参数时,Laravel 将自动将查询的作用域设置为通过其父级检索嵌套模型,使用约定来猜测父级上的关系名称。在这种情况下,将假定 User 模型具有名为 posts(路由参数名称的复数形式)的关系,可用于检索 Post 模型。

如果你愿意,你可以指示 Laravel 在未提供自定义键时也对“子”绑定进行作用域设置。为此,你可以在定义路由时调用 scopeBindings 方法:

php
use App\Models\Post;
use App\Models\User;

Route::get('/users/{user}/posts/{post}', function (User $user, Post $post) {
    return $post;
})->scopeBindings();

或者,你可以指示一组路由定义使用作用域绑定:

php
Route::scopeBindings()->group(function () {
    Route::get('/users/{user}/posts/{post}', function (User $user, Post $post) {
        return $post;
    });
});

同样,你可以通过调用 withoutScopedBindings 方法显式指示 Laravel 不对绑定进行作用域设置:

php
Route::get('/users/{user}/posts/{post:slug}', function (User $user, Post $post) {
    return $post;
})->withoutScopedBindings();

自定义缺失模型行为

通常,如果找不到隐式绑定的模型,将生成 404 HTTP 响应。但是,你可以通过在定义路由时调用 missing 方法来自定义此行为。missing 方法接受一个闭包,如果找不到隐式绑定的模型,将调用该闭包:

php
use App\Http\Controllers\LocationsController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Redirect;

Route::get('/locations/{location:slug}', [LocationsController::class, 'show'])
        ->name('locations.view')
        ->missing(function (Request $request) {
            return Redirect::route('locations.index');
        });

隐式枚举绑定

PHP 8.1 引入了对 枚举 的支持。为了补充此功能,Laravel 允许你在路由定义中类型提示 字符串支持的枚举,并且只有当该路由段对应于有效的枚举值时,Laravel 才会调用路由。否则,将自动返回 404 HTTP 响应。例如,给定以下枚举:

php
<?php

namespace App\Enums;

enum Category: string
{
    case Fruits = 'fruits';
    case People = 'people';
}

你可以定义一个路由,只有当 {category} 路由段为 fruitspeople 时才会调用。否则,Laravel 将返回 404 HTTP 响应:

php
use App\Enums\Category;
use Illuminate\Support\Facades\Route;

Route::get('/categories/{category}', function (Category $category) {
    return $category->value;
});

显式绑定

你不需要使用 Laravel 的隐式、基于约定的模型解析来使用模型绑定。你还可以显式定义路由参数如何对应于模型。要注册显式绑定,请使用路由器的 model 方法为给定参数指定类。你应该在 RouteServiceProvider 类的 boot 方法的开头定义显式模型绑定:

php
use App\Models\User;
use Illuminate\Support\Facades\Route;

/**
 * 定义你的路由模型绑定、模式过滤器等。
 *
 * @return void
 */
public function boot()
{
    Route::model('user', User::class);

    // ...
}

接下来,定义一个包含 {user} 参数的路由:

php
use App\Models\User;

Route::get('/users/{user}', function (User $user) {
    //
});

由于我们已将所有 {user} 参数绑定到 App\Models\User 模型,因此该类的实例将被注入到路由中。因此,例如,对 users/1 的请求将注入数据库中 ID 为 1User 实例。

如果在数据库中找不到匹配的模型实例,将自动生成 404 HTTP 响应。

自定义解析逻辑

如果你希望定义自己的模型绑定解析逻辑,可以使用 Route::bind 方法。传递给 bind 方法的闭包将接收 URI 段的值,并应返回应注入到路由中的类的实例。同样,此自定义应在应用程序的 RouteServiceProviderboot 方法中进行:

php
use App\Models\User;
use Illuminate\Support\Facades\Route;

/**
 * 定义你的路由模型绑定、模式过滤器等。
 *
 * @return void
 */
public function boot()
{
    Route::bind('user', function ($value) {
        return User::where('name', $value)->firstOrFail();
    });

    // ...
}

或者,你可以覆盖 Eloquent 模型上的 resolveRouteBinding 方法。此方法将接收 URI 段的值,并应返回应注入到路由中的类的实例:

php
/**
 * 检索绑定值的模型。
 *
 * @param  mixed  $value
 * @param  string|null  $field
 * @return \Illuminate\Database\Eloquent\Model|null
 */
public function resolveRouteBinding($value, $field = null)
{
    return $this->where('name', $value)->firstOrFail();
}

如果路由正在使用 隐式绑定作用域,则 resolveChildRouteBinding 方法将用于解析父模型的子绑定:

php
/**
 * 检索绑定值的子模型。
 *
 * @param  string  $childType
 * @param  mixed  $value
 * @param  string|null  $field
 * @return \Illuminate\Database\Eloquent\Model|null
 */
public function resolveChildRouteBinding($childType, $value, $field)
{
    return parent::resolveChildRouteBinding($childType, $value, $field);
}

回退路由

使用 Route::fallback 方法,你可以定义一个在没有其他路由匹配传入请求时将执行的路由。通常,未处理的请求将通过应用程序的异常处理程序自动呈现“404”页面。但是,由于你通常会在 routes/web.php 文件中定义 fallback 路由,因此 web 中间件组中的所有中间件将应用于该路由。你可以根据需要为此路由添加其他中间件:

php
Route::fallback(function () {
    //
});
exclamation

回退路由应始终是应用程序注册的最后一个路由。

速率限制

定义速率限制器

Laravel 包含强大且可自定义的速率限制服务,你可以利用这些服务来限制给定路由或路由组的流量。要开始,你应该定义符合应用程序需求的速率限制器配置。通常,这应该在应用程序的 App\Providers\RouteServiceProvider 类的 configureRateLimiting 方法中完成,该方法已经包含一个应用于应用程序的 routes/api.php 文件中的路由的速率限制器定义:

php
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;

/**
 * 配置应用程序的速率限制器。
 */
protected function configureRateLimiting(): void
{
    RateLimiter::for('api', function (Request $request) {
        return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
    });
}

速率限制器是使用 RateLimiter facade 的 for 方法定义的。for 方法接受速率限制器名称和一个返回应应用于分配给速率限制器的路由的限制配置的闭包。限制配置是 Illuminate\Cache\RateLimiting\Limit 类的实例。此类包含有用的“构建器”方法,以便你可以快速定义限制。速率限制器名称可以是你希望的任何字符串:

php
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;

/**
 * 配置应用程序的速率限制器。
 *
 * @return void
 */
protected function configureRateLimiting()
{
    RateLimiter::for('global', function (Request $request) {
        return Limit::perMinute(1000);
    });
}

如果传入的请求超过了指定的速率限制,Laravel 将自动返回一个 429 HTTP 状态码的响应。如果你希望定义速率限制应返回的自定义响应,可以使用 response 方法:

php
RateLimiter::for('global', function (Request $request) {
    return Limit::perMinute(1000)->response(function (Request $request, array $headers) {
        return response('Custom response...', 429, $headers);
    });
});

由于速率限制器回调接收传入的 HTTP 请求实例,你可以根据传入请求或已认证用户动态构建适当的速率限制:

php
RateLimiter::for('uploads', function (Request $request) {
    return $request->user()->vipCustomer()
                ? Limit::none()
                : Limit::perMinute(100);
});

分段速率限制

有时你可能希望按某个任意值分段速率限制。例如,你可能希望允许用户每分钟访问给定路由 100 次,每个 IP 地址。为此,你可以在构建速率限制时使用 by 方法:

php
RateLimiter::for('uploads', function (Request $request) {
    return $request->user()->vipCustomer()
                ? Limit::none()
                : Limit::perMinute(100)->by($request->ip());
});

为了使用另一个示例说明此功能,我们可以限制每个已认证用户 ID 每分钟 100 次访问路由,或每个 IP 地址每分钟 10 次访问路由:

php
RateLimiter::for('uploads', function (Request $request) {
    return $request->user()
                ? Limit::perMinute(100)->by($request->user()->id)
                : Limit::perMinute(10)->by($request->ip());
});

多个速率限制

如果需要,你可以为给定的速率限制器配置返回一个速率限制数组。每个速率限制将根据它们在数组中的顺序为路由进行评估:

php
RateLimiter::for('login', function (Request $request) {
    return [
        Limit::perMinute(500),
        Limit::perMinute(3)->by($request->input('email')),
    ];
});

将速率限制器附加到路由

速率限制器可以使用 throttle 中间件 附加到路由或路由组。throttle 中间件接受你希望分配给路由的速率限制器的名称:

php
Route::middleware(['throttle:uploads'])->group(function () {
    Route::post('/audio', function () {
        //
    });

    Route::post('/video', function () {
        //
    });
});

使用 Redis 进行限流

通常,throttle 中间件映射到 Illuminate\Routing\Middleware\ThrottleRequests 类。此映射在应用程序的 HTTP 内核 (App\Http\Kernel) 中定义。但是,如果你使用 Redis 作为应用程序的缓存驱动程序,你可能希望将此映射更改为使用 Illuminate\Routing\Middleware\ThrottleRequestsWithRedis 类。此类在使用 Redis 进行速率限制管理时更高效:

php
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequestsWithRedis::class,

表单方法欺骗

HTML 表单不支持 PUTPATCHDELETE 操作。因此,当定义从 HTML 表单调用的 PUTPATCHDELETE 路由时,你需要在表单中添加一个隐藏的 _method 字段。发送的 _method 字段的值将用作 HTTP 请求方法:

php
<form action="/example" method="POST">
    <input type="hidden" name="_method" value="PUT">
    <input type="hidden" name="_token" value="{{ csrf_token() }}">
</form>

为了方便起见,你可以使用 @method Blade 指令 生成 _method 输入字段:

php
<form action="/example" method="POST">
    @method('PUT')
    @csrf
</form>

访问当前路由

你可以使用 Route facade 上的 currentcurrentRouteNamecurrentRouteAction 方法来访问处理传入请求的路由的信息:

php
use Illuminate\Support\Facades\Route;

$route = Route::current(); // Illuminate\Routing\Route
$name = Route::currentRouteName(); // string
$action = Route::currentRouteAction(); // string

你可以参考 Route facade 的底层类Route 实例 的 API 文档,以查看路由器和路由类上可用的所有方法。

跨域资源共享 (CORS)

Laravel 可以自动响应 CORS OPTIONS HTTP 请求,使用你配置的值。所有 CORS 设置可以在应用程序的 config/cors.php 配置文件中配置。OPTIONS 请求将由默认包含在全局中间件堆栈中的 HandleCors 中间件 自动处理。你的全局中间件堆栈位于应用程序的 HTTP 内核 (App\Http\Kernel) 中。

lightbulb

有关 CORS 和 CORS 头的更多信息,请查阅 MDN Web 文档关于 CORS

路由缓存

在将应用程序部署到生产环境时,你应该利用 Laravel 的路由缓存。使用路由缓存将大大减少注册应用程序的所有路由所需的时间。要生成路由缓存,请执行 route:cache Artisan 命令:

shell
php artisan route:cache

运行此命令后,缓存的路由文件将在每个请求时加载。请记住,如果你添加了任何新路由,你将需要生成一个新的路由缓存。因此,你应该只在项目部署期间运行 route:cache 命令。

你可以使用 route:clear 命令清除路由缓存:

shell
php artisan route:clear