Laravel5.4 Vue 框架中 X-CSRF-TOKEN 的两种设置方法
Laravel5.4 中,Vue 框架引用了 Axios HTTP 库来处理后端请求,提供了一种比 Jquery 更轻量的解决方案,新框架也试图让一些操作更简洁和统一,比如常用的 X-CSRF-TOKEN 令牌设置。
第一次使用,通常会遇到一个 X-CSRF-TOKEN 的错误,编译完成,前端页面启动过程抛异常:
Uncaught TypeError: Cannot read property 'csrfToken' of undefined
at Object.<anonymous> (app.js:40921)
at __webpack_require__ (app.js:20)
at Object.<anonymous> (app.js:11198)
at __webpack_require__ (app.js:20)
at Object.<anonymous> (app.js:40943)
at __webpack_require__ (app.js:20)
at app.js:66
at app.js:69
查看编译后的 app.js,发现有一段对 X-CSRF-TOKEN 的处理,默认是从 window.Laravel 中获取:
window.axios.defaults.headers.common = {
'X-CSRF-TOKEN': window.Laravel.csrfToken,
// 'X-CSRF-TOKEN':document.querySelector('meta[name="csrf-token"]').getAttribute('content'),
'X-Requested-With': 'XMLHttpRequest'
};
这个变量没有设置,因此报错。
顺藤摸瓜,查源头,入口文件 app.js 引用了一个资源文件 resources/assets/js/bootstrap.js,其中对 X-CSRF-TOKEN 有定义
window.axios = require('axios');
window.axios.defaults.headers.common = {
'X-CSRF-TOKEN': window.Laravel.csrfToken,
'X-Requested-With': 'XMLHttpRequest'
};
正是这段处理,导致了前端页面的报错
其实,框架应该是有意为之,在初次调试的时候报错提示可以在这里统一处理 X-CSRF-TOKEN,但方式其实可以做得更优雅,应该在文档中给出最佳实践。
这里给出两种方案,大家可以按照实际情况采用:
一、从 meta 标记中获取(推荐)#
因为很多时候中间件也会检查 CSRF-TOKEN,所以通常我们都习惯在模板文件中设置 meta 标记来保存 CSRF-TOKEN,因此从这里统一获取,处理方式一致
<meta name="csrf-token" content="{{ csrf_token() }}">
因此,修改 bootstrap.js 对应代码为:
window.axios = require('axios');
window.axios.defaults.headers.common = {
'X-CSRF-TOKEN':document.querySelector('meta[name="csrf-token"]').getAttribute('content'),
'X-Requested-With': 'XMLHttpRequest'
};
这样的修改,通用性也更好。
二、直接在页面设置#
当然,如果使用通用模板,有些页面可能 meta 没有单独设置 csrf-token 标记,这种情况下,直接在页面用 js 脚本设置变量值也是一个办法,注意变量名和 bootstrap.js 中定义的保持一致
window.Laravel = <?php echo json_encode([
'csrfToken' => csrf_token(),
]); ?>
其他方式:#
通过命令行 php artisan make:auth 可以自动生成 layouts 模板文件:app.blade.php,里面包含了以上两种方法。
这个模板中还有其他关于登录态验证的最佳实践,大家可以参考(感谢 @yanyin 提供 tips)。
随着 Laravel 版本的迭代,更多前端开发流程框架被引入,节省了大量配置、调试时间。对比最近折腾 webpack+vue 遇到的各种坑,这种框架本身自带的流程框架确实非常有效率。
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: