1.基本路由
所有应用路由都定义在 App\Providers\RouteServiceProvider 类载入的 app/Http/routes.php 文件中。最基本的 Laravel 路由接收一个 URI 和一个闭包:
Route::get('foo', function () {
return 'Hello World';
});
Route::post('foo', function () {
//
});
2.有效的路由方法
Route::get($uri, $callback);
Route::post($uri, $callback);
Route::put($uri, $callback);
Route::patch($uri, $callback);
Route::delete($uri, $callback);
Route::options($uri, $callback);
3.match和any
Route::match(['get', 'post'], '/', function () {
//
});
Route::any('foo', function () {
//
});
4.路由参数
Route::get('user/{id}', function ($id) {
return 'User '.$id;
});
//定义多个路由参数,并且参数可以不一样如:comment,$commentId
Route::get('posts/{post}/comments/{comment}', function ($postId, $commentId) {
//
});
5.可选参数?标记
Route::get('user/{name?}', function ($name = null) {
return $name;
});
Route::get('user/{name?}', function ($name = 'John') {
return $name;
});
6.正则约束 where
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]+']);
全局约束
使用pattern方法。在RouteServiceProvider类的boot方法中定义约束模式:
/**
* 定义路由模型绑定,模式过滤器等
*
* @param \Illuminate\Routing\Router $router
* @return void
* @translator http://laravelacademy.org
*/
public function boot(Router $router){
$router->pattern('id', '[0-9]+');
parent::boot($router);
}
7.命名路由
命名路由为生成 URL 或重定向提供了便利。实现也很简单,在定义路由时使用数组键 as指定路由名称:
Route::get('user/profile', ['as' => 'profile', function () {
//
}]);
还可以通过在路由定义之后使用 name 方法链的方式来实现:
Route::get('user/profile', 'UserController@showProfile')->name('profile');
此外,还可以为控制器动作指定路由名称:??
Route::get('user/profile', [
'as' => 'profile', 'uses' => 'UserController@showProfile'
]);
8.路由群组 & 命名路由
Route::group(['as' => 'admin::'], function () {
Route::get('dashboard', ['as' => 'dashboard', function () {
// 路由被命名为 "admin::dashboard"
}]);
});
9.为命名路由生成URL
$url = route('profile');
$redirect = redirect()->route('profile');
return $redirect;//会跳转到profile
如果命名路由定义了参数,可以将该参数作为第二个参数传递给 route 函数。给定的路由参数将会自动插入 URL 中:
Route::get('user/{id}/profile', ['as' => 'profile', function ($id) {
//
}]);
$url = route('profile', ['id' => 1]);
10.路由群组
(1)中间件
Route::group(['middleware' => 'auth'], function () {
Route::get('/', function () {
// 使用 Auth 中间件
});
Route::get('user/profile', function () {
// 使用 Auth 中间件
});
});
(2)命名空间
Route::group(['namespace' => 'Admin'], function(){
// 控制器在 "App\Http\Controllers\Admin" 命名空间下
Route::group(['namespace' => 'User'], function(){
// 控制器在 "App\Http\Controllers\Admin\User" 命名空间下
});
});
,RouteServiceProvider引入 routes.php并指定其下所有控制器类所在的默认命名空间App\Http\Controllers,因此,我们在定义的时候只需要指定命名空间 App\Http\Controllers之后的部分即可。
(3)子域名路由
子域名可以像 URI 一样被分配给路由参数,从而允许捕获子域名的部分用于路由或者控制器,子域名可以通过群组属性数组中的 domain来指定:
Route::group(['domain' => '{account}.myapp.com'], function () {
Route::get('user/{id}', function ($account, $id) {
//
});
});
11.路由前缀prefix
Route::group(['prefix' => 'admin'], function () {
Route::get('users', function () {
// 匹配 "/admin/users" URL
});
});
指定公共路由参数
Route::group(['prefix' => 'accounts/{account_id}'], function () {
Route::get('detail', function ($account_id) {
// 匹配 accounts/{account_id}/detail URL
});
});
12.表单方法伪造
HTML 表单不支持 PUT、PATCH 或者 DELETE 请求方法,因此,当 PUT、PATCH 或 DELETE 路由时,需要添加一个隐藏的 _method
字段到表单中,其值被用作该表单的 HTTP 请求方法:
<form action="/foo/bar" method="POST">
<input type="hidden" name="_method" value="PUT">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
</form>
或者
<?php echo method_field('PUT'); ?>
或者
{{ method_field('PUT') }}
13.CSRF 攻击
Laravel 自动为每一个被应用管理的有效用户会话生成一个 CSRF “令牌”,该令牌用于验证授权用户和发起请求者是否是同一个人。想要生成包含 CSRF 令牌的隐藏输入字段,可以使用帮助函数 csrf_field来实现:
<?php echo csrf_field(); ?>
会生成如下代码
<input type="hidden" name="_token" value="<?php echo csrf_token(); ?>">
当然还可以使用 Blade 模板引擎提供的方式:
{!! csrf_field() !!}
你不需要自己编写代码去验证 POST、PUT 或者 DELETE 请求的 CSRF 令牌,因为 Laravel 自带的 HTTP 中间件VerifyCsrfToken会为我们做这项工作:将请求中输入的 token值和 Session 中的存储的 token作对比来进行验证。
从 CSRF 保护中排除指定 URL
你需要在 VerifyCsrfToken
中间件中将要排除的 URL 添加到 $except
属性:
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier;
class VerifyCsrfToken extends BaseVerifier
{
/**
*从CSRF验证中排除的URL
*
* @var array
*/
protected $except = [
'stripe/*',
];
}
X-CSRF-Token
除了将 CSRF 令牌作为 POST 参数进行验证外,还可以通过设置 X-CSRF-Token请求头来实现验证,VerifyCsrfToken 中间件会检查 X-CSRF-TOKEN请求头,首先创建一个 meta 标签并将令牌保存到该 meta 标签:
<meta name="csrf-token" content="{{ csrf_token() }}">
然后在 js 库(如 jQuery)中添加该令牌到所有请求头,这为基于 AJAX 的应用提供了简单、方便的方式来避免 CSRF 攻击:
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});