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 协议》,转载必须注明作者和本文链接
本帖由 Summer 于 8年前 加精
老财
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
讨论数量: 9
Summer

帮你修改了代码高亮 :smile_cat:

8年前 评论
老财

@Summer 完美!

8年前 评论

其实框架其实自带了 php artisan make:auth , 然后再 view 的模板文件中应用 layout 布局就可以。

8年前 评论
老财

@yanyin 确实也是一种方法,用命令生成的这种,两个方式都兼容。

8年前 评论

感谢科普,一直用的第二种方法,因为没有注意文档的推荐 - -

8年前 评论

'X-CSRF-TOKEN':document.querySelector('meta[name="csrf-token"]').getAttribute('content') ,
'X-Requested-With': 'XMLHttpRequest'
好像少了个逗号

8年前 评论

他这 token 请求之后 怎么刷新的呢?

7年前 评论
Peter335428

小夥伴呀

你是轉貼這篇文章吧?
https://iter01.com/238362.html

5年前 评论
老财 (楼主) 5年前