路由
基本路由
最基本的 Laravel 路由接受 URI 和闭包,提供了一种非常简单且富有表现力的方法来定义路由和行为,而无需复杂的路由配置文件
use Illuminate\Support\Facades\Route; Route::get('/greeting', function () { return 'Hello World';});
默认路由文件
所有 Laravel 路由都在您的路由文件中定义,这些文件位于 routes
目录中。这些文件由 Laravel 使用应用程序的 bootstrap/app.php
文件中指定的配置自动加载。routes/web.php
文件定义了用于您的 Web 界面的路由。这些路由被分配了 web
中间件组,它提供了会话状态和 CSRF 保护等功能。
对于大多数应用程序,您将首先在 routes/web.php
文件中定义路由。通过在浏览器中输入定义的路由的 URL,可以访问 routes/web.php
中定义的路由。例如,您可以通过在浏览器中导航到 http://example.com/user
来访问以下路由
use App\Http\Controllers\UserController; Route::get('/user', [UserController::class, 'index']);
API 路由
如果您的应用程序还将提供无状态 API,您可以使用 install:api
Artisan 命令启用 API 路由
php artisan install:api
install:api
命令安装 Laravel Sanctum,它提供了一个强大而简单的 API 令牌身份验证守卫,可用于验证第三方 API 消费者、SPA 或移动应用程序。此外,install:api
命令还会创建 routes/api.php
文件
Route::get('/user', function (Request $request) { return $request->user();})->middleware('auth:sanctum');
routes/api.php
中的路由是无状态的,并被分配给 api
中间件组。此外,/api
URI 前缀会自动应用于这些路由,因此您无需手动将其应用于文件中的每个路由。您可以通过修改应用程序的 bootstrap/app.php
文件来更改前缀
->withRouting( api: __DIR__.'/../routes/api.php', apiPrefix: 'api/admin', // ...)
可用的路由器方法
路由器允许您注册响应任何 HTTP 动词的路由
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
方法执行此操作。或者,您甚至可以使用 any
方法注册一个响应所有 HTTP 动词的路由
Route::match(['get', 'post'], '/', function () { // ...}); Route::any('/', function () { // ...});
定义多个共享同一 URI 的路由时,应在使用 any
、match
和 redirect
方法的路由之前定义使用 get
、post
、put
、patch
、delete
和 options
方法的路由。这确保了传入的请求与正确的路由匹配。
依赖注入
您可以在路由的回调签名中类型提示您的路由所需的任何依赖项。声明的依赖项将由 Laravel 服务容器自动解析并注入到回调中。例如,您可以类型提示 Illuminate\Http\Request
类,以便将当前的 HTTP 请求自动注入到您的路由回调中
use Illuminate\Http\Request; Route::get('/users', function (Request $request) { // ...});
CSRF 保护
请记住,任何指向 web
路由文件中定义的 POST
、PUT
、PATCH
或 DELETE
路由的 HTML 表单都应包含 CSRF 令牌字段。否则,请求将被拒绝。您可以在 CSRF 文档中阅读有关 CSRF 保护的更多信息
<form method="POST" action="/profile"> @csrf ...</form>
重定向路由
如果您正在定义重定向到另一个 URI 的路由,您可以使用 Route::redirect
方法。此方法提供了一个方便的快捷方式,因此您不必定义完整的路由或控制器来执行简单的重定向
Route::redirect('/here', '/there');
默认情况下,Route::redirect
返回 302
状态代码。您可以使用可选的第三个参数自定义状态代码
Route::redirect('/here', '/there', 301);
或者,您可以使用 Route::permanentRedirect
方法返回 301
状态代码
Route::permanentRedirect('/here', '/there');
在重定向路由中使用路由参数时,以下参数由 Laravel 保留,不能使用:destination
和 status
。
视图路由
如果您的路由只需要返回一个 视图,您可以使用 Route::view
方法。与 redirect
方法类似,此方法提供了一个简单的快捷方式,因此您不必定义完整的路由或控制器。view
方法接受 URI 作为其第一个参数,视图名称作为其第二个参数。此外,您可以提供一个数据数组作为可选的第三个参数传递给视图
Route::view('/welcome', 'welcome'); Route::view('/welcome', 'welcome', ['name' => 'Taylor']);
在视图路由中使用路由参数时,以下参数由 Laravel 保留,不能使用:view
、data
、status
和 headers
。
列出您的路由
route:list
Artisan 命令可以轻松提供应用程序定义的所有路由的概览
php artisan route:list
默认情况下,分配给每个路由的路由中间件不会显示在 route:list
输出中;但是,您可以通过向命令添加 -v
选项来指示 Laravel 显示路由中间件和中间件组名称
php artisan route:list -v # Expand middleware groups...php artisan route:list -vv
您还可以指示 Laravel 仅显示以给定 URI 开头的路由
php artisan route:list --path=api
此外,您可以通过在执行 route:list
命令时提供 --except-vendor
选项来指示 Laravel 隐藏由第三方包定义的任何路由
php artisan route:list --except-vendor
同样,您也可以通过在执行 route:list
命令时提供 --only-vendor
选项来指示 Laravel 仅显示由第三方包定义的路由
php artisan route:list --only-vendor
路由自定义
默认情况下,您的应用程序的路由由 bootstrap/app.php
文件配置和加载
<?php use Illuminate\Foundation\Application; return Application::configure(basePath: dirname(__DIR__)) ->withRouting( web: __DIR__.'/../routes/web.php', commands: __DIR__.'/../routes/console.php', health: '/up', )->create();
但是,有时您可能希望定义一个全新的文件来包含应用程序路由的子集。为此,您可以为 withRouting
方法提供 then
闭包。在此闭包中,您可以注册应用程序所需的任何其他路由
use Illuminate\Support\Facades\Route; ->withRouting( web: __DIR__.'/../routes/web.php', commands: __DIR__.'/../routes/console.php', health: '/up', then: function () { Route::middleware('api') ->prefix('webhooks') ->name('webhooks.') ->group(base_path('routes/webhooks.php')); },)
或者,您甚至可以通过向 withRouting
方法提供 using
闭包来完全控制路由注册。传递此参数时,框架不会注册任何 HTTP 路由,并且您负责手动注册所有路由
use Illuminate\Support\Facades\Route; ->withRouting( commands: __DIR__.'/../routes/console.php', using: function () { Route::middleware('api') ->prefix('api') ->group(base_path('routes/api.php')); Route::middleware('web') ->group(base_path('routes/web.php')); },)
路由参数
必需参数
有时您需要在路由中捕获 URI 的段。例如,您可能需要从 URL 中捕获用户的 ID。您可以通过定义路由参数来实现
Route::get('/user/{id}', function (string $id) { return 'User '.$id;});
你可以在路由中定义任意数量的路由参数。
Route::get('/posts/{post}/comments/{comment}', function (string $postId, string $commentId) { // ...});
路由参数总是用 {}
大括号括起来,并且应该由字母字符组成。下划线 (_
) 在路由参数名称中也是可以接受的。路由参数会根据它们在路由定义中的顺序注入到路由回调或控制器中 - 路由回调或控制器参数的名称并不重要。
参数和依赖注入
如果你的路由有依赖关系,并且你希望 Laravel 服务容器自动将这些依赖注入到你的路由回调中,你应该将你的路由参数列在依赖项之后。
use Illuminate\Http\Request; Route::get('/user/{id}', function (Request $request, string $id) { return 'User '.$id;});
可选参数
有时,你可能需要指定一个不一定总是在 URI 中存在的路由参数。你可以通过在参数名称后放置 ?
标记来实现。请确保为路由的相应变量提供默认值。
Route::get('/user/{name?}', function (?string $name = null) { return $name;}); Route::get('/user/{name?}', function (?string $name = 'John') { return $name;});
正则表达式约束
你可以使用路由实例上的 where
方法来约束路由参数的格式。where
方法接受参数的名称和一个定义参数应该如何约束的正则表达式。
Route::get('/user/{name}', function (string $name) { // ...})->where('name', '[A-Za-z]+'); Route::get('/user/{id}', function (string $id) { // ...})->where('id', '[0-9]+'); Route::get('/user/{id}/{name}', function (string $id, string $name) { // ...})->where(['id' => '[0-9]+', 'name' => '[a-z]+']);
为了方便起见,一些常用的正则表达式模式有辅助方法,允许你快速向路由添加模式约束。
Route::get('/user/{id}/{name}', function (string $id, string $name) { // ...})->whereNumber('id')->whereAlpha('name'); Route::get('/user/{name}', function (string $name) { // ...})->whereAlphaNumeric('name'); Route::get('/user/{id}', function (string $id) { // ...})->whereUuid('id'); Route::get('/user/{id}', function (string $id) { // ...})->whereUlid('id'); Route::get('/category/{category}', function (string $category) { // ...})->whereIn('category', ['movie', 'song', 'painting']); Route::get('/category/{category}', function (string $category) { // ...})->whereIn('category', CategoryEnum::cases());
如果传入的请求与路由模式约束不匹配,将返回 404 HTTP 响应。
全局约束
如果你希望一个路由参数始终受给定的正则表达式约束,你可以使用 pattern
方法。你应在应用程序的 App\Providers\AppServiceProvider
类的 boot
方法中定义这些模式。
use Illuminate\Support\Facades\Route; /** * Bootstrap any application services. */public function boot(): void{ Route::pattern('id', '[0-9]+');}
一旦定义了模式,它将自动应用于所有使用该参数名称的路由。
Route::get('/user/{id}', function (string $id) { // Only executed if {id} is numeric...});
编码后的正斜杠
Laravel 路由组件允许除了 /
之外的所有字符出现在路由参数值中。你必须使用 where
条件正则表达式显式允许 /
作为占位符的一部分。
Route::get('/search/{search}', function (string $search) { return $search;})->where('search', '.*');
编码后的正斜杠仅在最后一个路由段中受支持。
命名路由
命名路由允许方便地生成特定路由的 URL 或重定向。你可以通过将 name
方法链接到路由定义来为路由指定名称。
Route::get('/user/profile', function () { // ...})->name('profile');
你也可以为控制器动作指定路由名称。
Route::get( '/user/profile', [UserProfileController::class, 'show'])->name('profile');
路由名称应该始终是唯一的。
生成命名路由的 URL
一旦你为给定的路由分配了名称,你可以在通过 Laravel 的 route
和 redirect
辅助函数生成 URL 或重定向时使用该路由的名称。
// Generating URLs...$url = route('profile'); // Generating Redirects...return redirect()->route('profile'); return to_route('profile');
如果命名路由定义了参数,你可以将参数作为第二个参数传递给 route
函数。给定的参数将自动按照它们在生成的 URL 中的正确位置插入。
Route::get('/user/{id}/profile', function (string $id) { // ...})->name('profile'); $url = route('profile', ['id' => 1]);
如果你在数组中传递额外的参数,这些键值对将自动添加到生成的 URL 的查询字符串中。
Route::get('/user/{id}/profile', function (string $id) { // ...})->name('profile'); $url = route('profile', ['id' => 1, 'photos' => 'yes']); // /user/1/profile?photos=yes
有时,你可能希望为 URL 参数指定请求范围的默认值,例如当前语言环境。为了实现这一点,你可以使用 URL::defaults
方法。
检查当前路由
如果你想确定当前请求是否被路由到给定的命名路由,你可以使用 Route 实例上的 named
方法。例如,你可以从路由中间件中检查当前路由名称。
use Closure;use Illuminate\Http\Request;use Symfony\Component\HttpFoundation\Response; /** * Handle an incoming request. * * @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next */public function handle(Request $request, Closure $next): Response{ if ($request->route()->named('profile')) { // ... } return $next($request);}
路由组
路由组允许你在大量路由中共享路由属性,例如中间件,而无需在每个单独的路由上定义这些属性。
嵌套组尝试智能地将属性与其父组“合并”。中间件和 where
条件被合并,而名称和前缀被附加。名称空间分隔符和 URI 前缀中的斜杠会在适当的地方自动添加。
中间件
要将 中间件 分配给组中的所有路由,你可以在定义组之前使用 middleware
方法。中间件按照它们在数组中列出的顺序执行。
Route::middleware(['first', 'second'])->group(function () { Route::get('/', function () { // Uses first & second middleware... }); Route::get('/user/profile', function () { // Uses first & second middleware... });});
控制器
如果一组路由都使用相同的 控制器,你可以使用 controller
方法为组中的所有路由定义公共控制器。然后,在定义路由时,你只需要提供它们调用的控制器方法。
use App\Http\Controllers\OrderController; Route::controller(OrderController::class)->group(function () { Route::get('/orders/{id}', 'show'); Route::post('/orders', 'store');});
子域名路由
路由组也可用于处理子域名路由。子域名可以像路由 URI 一样被分配路由参数,允许你捕获子域名的一部分以在你的路由或控制器中使用。可以通过在定义组之前调用 domain
方法来指定子域名。
Route::domain('{account}.example.com')->group(function () { Route::get('/user/{id}', function (string $account, string $id) { // ... });});
为了确保你的子域名路由可访问,你应该在注册根域名路由之前注册子域名路由。这将防止具有相同 URI 路径的根域名路由覆盖子域名路由。
路由前缀
prefix
方法可用于为组中的每个路由添加给定的 URI 前缀。例如,你可能希望为组中的所有路由 URI 添加 admin
前缀。
Route::prefix('admin')->group(function () { Route::get('/users', function () { // Matches The "/admin/users" URL });});
路由名称前缀
name
方法可用于为组中的每个路由名称添加给定的字符串前缀。例如,你可能希望为组中所有路由的名称添加 admin
前缀。给定的字符串将按照指定的方式精确地添加到路由名称前缀,因此我们确保在添加前缀时提供尾随的 .
字符。
Route::name('admin.')->group(function () { Route::get('/users', function () { // Route assigned name "admin.users"... })->name('users');});
路由模型绑定
当将模型 ID 注入到路由或控制器动作时,你通常会查询数据库以检索与该 ID 对应的模型。Laravel 路由模型绑定提供了一种方便的方法,可以将模型实例直接自动注入到你的路由中。例如,你可以注入与给定 ID 匹配的整个 User
模型实例,而不是注入用户的 ID。
隐式绑定
Laravel 会自动解析路由或控制器动作中定义的 Eloquent 模型,这些模型的类型提示变量名称与路由段名称匹配。例如
use App\Models\User; Route::get('/users/{user}', function (User $user) { return $user->email;});
由于 $user
变量类型提示为 App\Models\User
Eloquent 模型,并且变量名称与 {user}
URI 段匹配,Laravel 将自动注入具有与请求 URI 中的相应值匹配的 ID 的模型实例。如果在数据库中未找到匹配的模型实例,将自动生成 404 HTTP 响应。
当然,在使用控制器方法时也可以进行隐式绑定。同样,请注意 {user}
URI 段与控制器中的 $user
变量匹配,其中包含 App\Models\User
类型提示。
use App\Http\Controllers\UserController;use App\Models\User; // Route definition...Route::get('/users/{user}', [UserController::class, 'show']); // Controller method definition...public function show(User $user){ return view('user.profile', ['user' => $user]);}
软删除模型
通常,隐式模型绑定不会检索已被 软删除 的模型。但是,你可以通过将 withTrashed
方法链接到路由的定义来指示隐式绑定检索这些模型。
use App\Models\User; Route::get('/users/{user}', function (User $user) { return $user->email;})->withTrashed();
自定义键
有时,你可能希望使用除 id
以外的列来解析 Eloquent 模型。为此,你可以在路由参数定义中指定列。
use App\Models\Post; Route::get('/posts/{post:slug}', function (Post $post) { return $post;});
如果你希望模型绑定在检索给定的模型类时始终使用除 id
以外的数据库列,你可以重写 Eloquent 模型上的 getRouteKeyName
方法。
/** * Get the route key for the model. */public function getRouteKeyName(): string{ return 'slug';}
自定义键和范围
当在单个路由定义中隐式绑定多个 Eloquent 模型时,你可能希望将第二个 Eloquent 模型的作用域设置为它必须是前一个 Eloquent 模型的子模型。例如,考虑以下路由定义,该路由通过 slug 为特定用户检索博客文章
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
方法。
use App\Models\Post;use App\Models\User; Route::get('/users/{user}/posts/{post}', function (User $user, Post $post) { return $post;})->scopeBindings();
或者,你可以指示一组完整的路由定义使用作用域绑定。
Route::scopeBindings()->group(function () { Route::get('/users/{user}/posts/{post}', function (User $user, Post $post) { return $post; });});
同样,你可以通过调用 withoutScopedBindings
方法来显式指示 Laravel 不对绑定进行作用域限定。
Route::get('/users/{user}/posts/{post:slug}', function (User $user, Post $post) { return $post;})->withoutScopedBindings();
自定义缺少模型的行为
通常,如果找不到隐式绑定的模型,将生成 404 HTTP 响应。但是,你可以通过在定义路由时调用 missing
方法来自定义此行为。missing
方法接受一个闭包,如果找不到隐式绑定的模型,该闭包将被调用。
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 允许你在路由定义上类型提示一个 Backed 枚举,并且仅当该路由段对应于有效的枚举值时,Laravel 才会调用该路由。否则,将自动返回 404 HTTP 响应。例如,给定以下枚举
<?php namespace App\Enums; enum Category: string{ case Fruits = 'fruits'; case People = 'people';}
你可以定义一个路由,该路由仅在 {category}
路由段为 fruits
或 people
时调用。否则,Laravel 将返回 404 HTTP 响应。
use App\Enums\Category;use Illuminate\Support\Facades\Route; Route::get('/categories/{category}', function (Category $category) { return $category->value;});
显式绑定
你不需要使用 Laravel 基于隐式约定的模型解析来使用模型绑定。你还可以显式定义路由参数如何对应于模型。要注册显式绑定,请使用路由器的 model
方法为给定的参数指定类。你应该在 AppServiceProvider
类的 boot
方法的开头定义你的显式模型绑定。
use App\Models\User;use Illuminate\Support\Facades\Route; /** * Bootstrap any application services. */public function boot(): void{ Route::model('user', User::class);}
接下来,定义一个包含 {user}
参数的路由。
use App\Models\User; Route::get('/users/{user}', function (User $user) { // ...});
由于我们已将所有 {user}
参数绑定到 App\Models\User
模型,因此该类的实例将被注入到路由中。因此,例如,对 users/1
的请求将从数据库中注入 ID 为 1
的 User
实例。
如果在数据库中未找到匹配的模型实例,将自动生成 404 HTTP 响应。
自定义解析逻辑
如果你希望定义自己的模型绑定解析逻辑,可以使用 Route::bind
方法。你传递给 bind
方法的闭包将接收 URI 段的值,并应返回应该注入到路由中的类实例。同样,此自定义应该在应用程序的 AppServiceProvider
类的 boot
方法中进行。
use App\Models\User;use Illuminate\Support\Facades\Route; /** * Bootstrap any application services. */public function boot(): void{ Route::bind('user', function (string $value) { return User::where('name', $value)->firstOrFail(); });}
或者,你可以在你的 Eloquent 模型上重写 resolveRouteBinding
方法。该方法将接收 URI 段的值,并应返回应该注入到路由中的类实例。
/** * Retrieve the model for a bound value. * * @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
方法将被用于解析父模型的子绑定。
/** * Retrieve the child model for a bound value. * * @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
中间件组中的所有中间件都将应用于该路由。你可以根据需要自由地向此路由添加其他中间件。
Route::fallback(function () { // ...});
速率限制
定义速率限制器
Laravel 包含了强大且可自定义的速率限制服务,你可以使用它们来限制给定路由或路由组的流量。要开始使用,你应该定义满足你的应用程序需求的速率限制器配置。
速率限制器可以在你的应用程序的 App\Providers\AppServiceProvider
类的 boot
方法中定义。
use Illuminate\Cache\RateLimiting\Limit;use Illuminate\Http\Request;use Illuminate\Support\Facades\RateLimiter; /** * Bootstrap any application services. */protected function boot(): void{ RateLimiter::for('api', function (Request $request) { return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip()); });}
速率限制器使用 RateLimiter
门面的 for
方法定义。for
方法接受一个速率限制器名称和一个闭包,该闭包返回应应用于分配给该速率限制器的路由的限制配置。限制配置是 Illuminate\Cache\RateLimiting\Limit
类的实例。该类包含有用的“构建器”方法,以便你可以快速定义你的限制。速率限制器名称可以是任何你想要的字符串。
use Illuminate\Cache\RateLimiting\Limit;use Illuminate\Http\Request;use Illuminate\Support\Facades\RateLimiter; /** * Bootstrap any application services. */protected function boot(): void{ RateLimiter::for('global', function (Request $request) { return Limit::perMinute(1000); });}
如果传入的请求超过了指定的速率限制,Laravel 将自动返回一个带有 429 HTTP 状态码的响应。如果你想定义自己的速率限制返回的响应,你可以使用 response
方法。
RateLimiter::for('global', function (Request $request) { return Limit::perMinute(1000)->response(function (Request $request, array $headers) { return response('Custom response...', 429, $headers); });});
由于速率限制器回调接收传入的 HTTP 请求实例,你可以根据传入的请求或经过身份验证的用户动态构建适当的速率限制。
RateLimiter::for('uploads', function (Request $request) { return $request->user()->vipCustomer() ? Limit::none() : Limit::perMinute(100);});
分段速率限制
有时你可能希望按某些任意值来分段速率限制。例如,你可能希望允许用户按 IP 地址每分钟访问给定的路由 100 次。要实现这一点,你可以在构建速率限制时使用 by
方法。
RateLimiter::for('uploads', function (Request $request) { return $request->user()->vipCustomer() ? Limit::none() : Limit::perMinute(100)->by($request->ip());});
为了用另一个例子说明此功能,我们可以限制路由的访问,对于已通过身份验证的用户,每分钟 100 次,对于访客,按 IP 地址每分钟 10 次。
RateLimiter::for('uploads', function (Request $request) { return $request->user() ? Limit::perMinute(100)->by($request->user()->id) : Limit::perMinute(10)->by($request->ip());});
多个速率限制
如果需要,你可以为给定的速率限制器配置返回一个速率限制数组。将根据它们在数组中的放置顺序评估每个路由的速率限制。
RateLimiter::for('login', function (Request $request) { return [ Limit::perMinute(500), Limit::perMinute(3)->by($request->input('email')), ];});
如果你正在分配多个按相同的 by
值分段的速率限制,你应该确保每个 by
值都是唯一的。实现此目的的最简单方法是在传递给 by
方法的值前加上前缀。
RateLimiter::for('uploads', function (Request $request) { return [ Limit::perMinute(10)->by('minute:'.$request->user()->id), Limit::perDay(1000)->by('day:'.$request->user()->id), ];});
将速率限制器附加到路由
可以使用 throttle
中间件将速率限制器附加到路由或路由组。throttle 中间件接受你要分配给路由的速率限制器的名称。
Route::middleware(['throttle:uploads'])->group(function () { Route::post('/audio', function () { // ... }); Route::post('/video', function () { // ... });});
使用 Redis 进行节流
默认情况下,throttle
中间件映射到 Illuminate\Routing\Middleware\ThrottleRequests
类。但是,如果你使用 Redis 作为应用程序的缓存驱动程序,你可能希望指示 Laravel 使用 Redis 来管理速率限制。为此,你应该在应用程序的 bootstrap/app.php
文件中使用 throttleWithRedis
方法。此方法将 throttle
中间件映射到 Illuminate\Routing\Middleware\ThrottleRequestsWithRedis
中间件类。
->withMiddleware(function (Middleware $middleware) { $middleware->throttleWithRedis(); // ...})
表单方法欺骗
HTML 表单不支持 PUT
、PATCH
或 DELETE
操作。因此,当定义从 HTML 表单调用的 PUT
、PATCH
或 DELETE
路由时,你需要向表单添加一个隐藏的 _method
字段。与 _method
字段一起发送的值将用作 HTTP 请求方法。
<form action="/example" method="POST"> <input type="hidden" name="_method" value="PUT"> <input type="hidden" name="_token" value="{{ csrf_token() }}"></form>
为方便起见,你可以使用 @method
Blade 指令 来生成 _method
输入字段。
<form action="/example" method="POST"> @method('PUT') @csrf</form>
访问当前路由
你可以使用 Route
门面上的 current
、currentRouteName
和 currentRouteAction
方法来访问有关处理传入请求的路由的信息。
use Illuminate\Support\Facades\Route; $route = Route::current(); // Illuminate\Routing\Route$name = Route::currentRouteName(); // string$action = Route::currentRouteAction(); // string
你可以参考 Route 门面的底层类 和 Route 实例 的 API 文档,以查看路由器和路由类上的所有可用方法。
跨域资源共享 (CORS)
Laravel 可以自动使用你配置的值来响应 CORS OPTIONS
HTTP 请求。OPTIONS
请求将由自动包含在应用程序的全局中间件堆栈中的 HandleCors
中间件自动处理。
有时,你可能需要自定义应用程序的 CORS 配置值。你可以通过使用 config:publish
Artisan 命令发布 cors
配置文件来做到这一点。
php artisan config:publish cors
此命令将在应用程序的 config
目录中放置一个 cors.php
配置文件。
有关 CORS 和 CORS 标头的更多信息,请查阅 MDN Web 上关于 CORS 的文档。
路由缓存
在将应用程序部署到生产环境时,你应该利用 Laravel 的路由缓存。使用路由缓存将大大减少注册应用程序的所有路由所需的时间。要生成路由缓存,请执行 route:cache
Artisan 命令。
php artisan route:cache
运行此命令后,你的缓存路由文件将在每次请求时加载。请记住,如果你添加任何新路由,则需要生成新的路由缓存。因此,你只能在项目的部署期间运行 route:cache
命令。
你可以使用 route:clear
命令清除路由缓存。
php artisan route:clear