前言:之前在学习并使用 Laravel 框架过程中,全是碎片化掌握,现在重新学习并记录一次学习的过程。
本文内容对应
Laravel8.*
版本。
Laravel 直达入口:
一、视图
Laravel 的视图文件存放于
resources/views
目录中。
1.1 创建视图
<!-- View stored in resources/views/greeting.blade.php -->
<html>
<body>
<h1>Hello, {{ $name }}</h1>
</body>
</html>
将上述代码保存至
resources/views/greeting.blade.php
文件后,就可以通过view
助手函数返回。
view
助手函数的第一个参数为 视图模板的名称,第二个参数为可供视图的数据数组。
Route::get('/', function () { return view('greeting', ['name' => 'James']); });
也可将模板保存至
views
的子目录。使用点 .
引用嵌套视图。return view('admin.profile', $data);
1.2 判断视图是否存在
use Illuminate\Support\Facades\View;
# 如果存在,则会返回 true
if (View::exists('emails.customer')) {
//
}
1.3 向视图传递数据
使用
view
助手函数的第二个参数使用
view
助手函数链式调用with
方法return view('greeting')->with('name', 'Victoria');
1.4 与所有视图共享数据
有时,有一些公共数据需要在所有页面都展示,这时,你就可以在 服务提供器的
boot
方法中调用视图门面的share
方法。例如<?php namespace App\Providers; use Illuminate\Support\Facades\View; class AppServiceProvider extends ServiceProvider { /** * Register any application services. * * @return void */ public function register() { // } /** * Bootstrap any application services. * * @return void */ public function boot() { View::share('key', 'value'); } }
二、视图合成器
视图合成器是调用视图时的回调或者类方法。在视图即将渲染时执行。
默认没有存放 视图合成器 的目录,例如可以新建并存放在
app/Http/View/Composers
目录中。
使用
View
门面调用composer
方法,即可在视图渲染之前被调用。
2.1 创建视图合成器
接下来的示例步骤是:
- 创建服务提供者并注册
- 在服务提供者的
boot
方法中,调用composer
方法,定义视图合成器- 定义视图合成器调用类
-
创建服务提供者,并在
config/app.php
文件中的providers
数组中注册<?php namespace App\Providers; use Illuminate\Support\Facades\View; use Illuminate\Support\ServiceProvider; class ViewServiceProvider extends ServiceProvider { /** * Register any application services. * * @return void */ public function register() { // } /** * Bootstrap any application services. * * @return void */ public function boot() { # 2. 在服务提供者的 `boot` 方法中,调用 `composer` 方法,定义视图合成器 // Using class based composers... View::composer( 'profile', 'App\Http\View\Composers\ProfileComposer' ); // Using Closure based composers... View::composer('dashboard', function ($view) { // }); } }
-
定义视图合成器调用类
<?php namespace App\Http\View\Composers; use App\Repositories\UserRepository; use Illuminate\View\View; class ProfileComposer { /** * The user repository implementation. * * @var UserRepository */ protected $users; /** * Create a new profile composer. * * @param UserRepository $users * @return void */ public function __construct(UserRepository $users) { // Dependencies automatically resolved by service container... $this->users = $users; } /** * Bind data to the view. * * @param View $view * @return void */ public function compose(View $view) { $view->with('count', $this->users->count()); } }
所有的视图合成器都会通过 服务容器 进行解析,所以你可以在视图合成器的构造函数中类型提示需要注入的依赖项。
2.2 将视图合成器添加到多个视图
通过
composer
方法的第一个参数传入 视图数组,就可以将多个视图添加到视图合成器中。
通过
composer
方法的第一个参数传入星号 *
,就可以将所有视图添加到视图合成器中。
# 多个
View::composer(
['profile', 'dashboard'],
'App\Http\View\Composers\MyViewComposer'
);
# 所有
View::composer('*', function ($view) {
//
});
三、视图构造器
与视图合成器不同的是,视图构造器在 视图实例化之后执行。
其他使用方法与视图合成器相同。
使用
View
门面的creator
方法生成视图构造器。
View::creator('profile', 'App\Http\View\Creators\ProfileCreator');
四、视图优化
官网说的很明白,恩。😂
总结一下就是:
- 视图如果没有被编译,则会进行编译。
- 视图如果已经被编译,则会比较是否被修改,如果被修改则重新编译。
4.1 视图预编译
# 控制台命令,预编译所有视图文件
php artisan view:cache
4.2 清除视图缓存
# 控制台命令,清除视图缓存
php artisan view:clear
五、CSRF 保护
CSRF 是一种跨站请求伪造的恶意攻击,凭借已通过身份验证的用户来运行未经过授权的命令。 如何防止 CSRF 攻击
Laravel 为每个用户的会话生成一个
CSRF 令牌
,该令牌用于验证经过身份验证的用户是否是向应用程序发出请求的用户。
5.1 生成令牌
在 HTML 表单中,包含一个隐藏的 csrf 标记字段即可,提交后,在
web
中间件线里的VerifyCsrfToken
中间件会自动验证请求的令牌与存储在会话中的令牌是否匹配。<form method="POST" action="/profile"> @csrf ... </form>
5.2 白名单
官网的举例场景在实战中确实存在。我们一起来看一看。
有时候你可能希望设置一组不需要的 CSRF 保护的 URL 。例如,如果你正在使用 Stripe 处理付款并使用了他们的 webhook 系统,你会需要从 CSRF 的保护中排除 Stripe webhook 处理程序路由,因为 Stripe 并不会给你的路由发送 CSRF 令牌。
这时怎么办,典型做法,就是不要把这类路由放到
routes/web.php
中。
但通过 Laravel ,可以在
app/Http/Middleware/VerifyCsrfToken.php
中间件文件中,将不需要 CSRF 验证的 URL 放到$except
属性中。
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
class VerifyCsrfToken extends Middleware
{
/**
* 从 CSRF 验证中排除的 URI
*
* @var array
*/
protected $except = [
'stripe/*',
'http://example.com/foo/bar',
'http://example.com/foo/*',
];
}
5.3 X-CSRF-TOKEN
除了检查 POST 参数中的 CSRF 令牌外,
VerifyCsrfToken
中间件还会检查X-CSRF-TOKEN
请求头。你应该将令牌保存在 HTMLmeta
标签中,如下:
<meta name="csrf-token" content="{{ csrf_token() }}">
然后,一旦创建了
mata
标签,就可以指示类似 jQuery 库自动将令牌添加到所有的请求头信息中,还可以为ajax
提供 CSRF 保护。例如:$.ajaxSetup({ headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') } });
5.4 X-XSRF-TOKEN
Laravel 将当前的 CSRF 令牌存储在一个
XSRF-TOKEN
cookie
中,该 cookie 包含在框架生成的每个响应中。你可以使用 cookie 值来设置X-XSRF-TOKEN
请求头。
这个 cookie 主要是作为一种方便的方式发送的,因为一些 JavaScript 框架和库,例如 Angular 和 Axios ,会自动将它的值放入
X-XSRF-TOKEN
头中。
技巧:默认情况下,
resources/js/bootstrap.js
文件包含的 Axios HTTP 库,会自动为你发送 CSRF 令牌。