Laravel 应用的入口:路由系列之基础入门篇
基本路由
最基本的 Laravel 路由只接收一个 URI 和一个闭包,并以此为基础提供一个非常简单优雅的路由定义方法:Route::get('hello', function () {
return 'Hello, Welcome to LaravelAcademy.org';
});
我们以在安装配置文档中新建的 blog
应用为例,在 routes/web.php
中定义该路由:
在浏览器中通过 http://blog.dev/hello
(我使用 Valet 作为开发环境,故而对应域名是 blog.dev
,实际域名以自己配置的为准)即可访问我们刚刚定义的路由,页面输出内容如下:
Hello, welcome to LaravelAcademy.org
默认路由文件
所有 Laravel 路由都定义在位于routes
目录下的路由文件中,这些文件通过框架自动加载,相应逻辑位于 app/Providers/RouteServiceProvider
类(后面我们在讲 Laravel 启动过程的时候会详细讨论这部分逻辑)。routes/web.php
文件定义了 Web 界面的路由,这些路由被分配到了 web
中间件组,从而可以使用 session 和 csrf 保护等功能。routes/api.php
中的路由是无状态的,这是因为被分配到了 api
中间件组。
对大多数应用而言,都是从 routes/web.php
文件开始定义路由。定义在 routes/web.php
中的路由可以通过在浏览器地址栏输入相应的 URL 进行访问,例如,你可以通过 http://blog.dev/user
访问下面的路由:
Route::get('/user', 'UsersController@index');
正如前面所提到的,定义在 routes/api.php
文件中的路由通过 app/Providers/RouteServiceProvider
的处理被嵌套在一个路由中间件组中,在这个路由中间件组中,所有路由会被自动添加 /api
前缀,所以你不需要再到路由文件中为每个路由手动添加,你可以通过编辑 RouteServiceProvider
类来修改路由前缀以及其他的路由中间件组选项:
支持的请求方式
我们可以注册路由来响应任何 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'], 'foo', function () {
return 'This is a request from get or post';
});
Route::any('bar', function () {
return 'This is a request from any HTTP verb';
});
测试 GET 请求的时候直接在浏览器中输入请求地址即可,测试 POST 请求可以通过客户端工具,比如 Advanced REST Client,该工具可以在 Chrome 应用商店下载到,此外如果上面的路由是定义在 routes/web.php
的话,在测试 POST 请求之前,需要将对应路由取消 CSRF 保护检查,否则会返回 419
状态码导致无法请求成功,取消的方法是在 app/Http/Middleware/VerifyCsrfToken
中设置排除检查路由:
下面我们来测试下 POST 请求:
如果路由是定义在 routes/api.php
的话,则无需关注 CSRF 保护问题,比如我们在 routes/api.php
定义 bar
路由,并且在 VerifyCsrfToken
的 $except
属性数组中移除 bar
,然后我们测试下对 http://blog.dev/api/bar
的 POST 请求:
正如我们所预测的,完全没有任何问题,背后的原因是因为 web
路由文件中定义的路由都位于 web
中间件组,该中间件组默认启用 CSRF 保护检查,而 api
路由文件位于 api
中间件组,该中间件组下的路由主要用于 第三方 API 请求,没办法进行 CSRF 检查,所以不需要做任何处理。
CSRF 保护
在routes/web.php
路由文件中所有请求方式为 PUT
、POST
或 DELETE
的路由对应的 HTML 表单都必须包含一个 CSRF 令牌字段,否则,请求会被拒绝。关于 CSRF 的更多细节,可以参考 CSRF文档:
<form method="POST" action="/profile">
{{ csrf_field() }}
...
</form>
还是以上面的 foo
路由为例,如果我们不在 VerifyCsrfToken
中间件中排除对它的检查(事实上,这样的操作也不安全),那么就需要在表单提交中带上 csrf_token
字段:
这样,当我们访问 http://blog.dev/form
然后在页面点击提交按钮后,页面会跳转到 http://blog.dev/foo
并显示如下内容:
This is a request from get or post
表单方法伪造
HTML 表单不支持PUT
、PATCH
或者 DELETE
请求方法,因此,在 HTML 表单中调用 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>
还可以直接使用辅助函数 method_field
来实现这一功能:
{{ method_field('PUT') }}
路由重定向
如果你需要定义一个重定向到其他 URI 的路由,可以使用Route::redirect
方法,该方法非常方便,以至于你不需要再定义额外的路由或控制器来执行简单的重定向逻辑:
Route::redirect('/here', '/there', 301);
其中 here
表示原路由,there
表示重定向之后的路由,301
是一个 HTTP 状态码,用于标识重定向。
路由视图
如果你的路由需要返回一个视图,可以使用Route::view
方法,和 redirect
方法类似,这个方法也很方便,以至于你不需要在额外定义一个路由或控制器。view
方法接收一个 URI 作为第一个参数,以及一个视图名称作为第二个参数,此外,你还可以提供一个数组数据传递到该视图方法作为可选的第三个参数,该数组数据可用于视图中的数据渲染:
Route::view('/welcome', 'welcome');
Route::view('/welcome', 'welcome', ['name' => '学院君']);
我们在 routes/web.php 定义一个路由视图如下:
为了保证可以共用 welcome.blade.php
这个视图文件,我们也对默认提供的 /
路由做了调整,接下来,我们需要修改 resources/views/welcome.blade.php
代码以支持 website
数据变量:
我们将原来写死的 Laravel
文本调整为支持变量传入的方式,这样,我们就可以在浏览器中通过 http://blog.dev/view
访问路由视图了:
27 Comments
route::view报错
我也是,据说是要指向域名,但是不知道在哪指向
学院君,请问在哪指向呢,我是直接在“/foo"前面加上项目的路径