在 laravel 中使用 AJAX 防止令牌不匹配异常的方法

Ways to prevent TokenMismatch Exception using AJAX in laravel

我分析过出现Token Mismatch Error的比例很高。这个错误是因为一些愚蠢的错误。开发人员犯错的原因有很多。以下是一些示例。

  1. 未在 header 上发送 _token
  2. 使用 ajax 时不发送数据 _token
  3. 没有存储路径权限。
  4. 无效Session存储路径。

还有很多其他原因,请随时编辑此问题以获取更多防止此类错误的方法。

可能的变化 - 1

在 Header

上设置令牌

在您的 default.blade.php 视图 <head> 上设置令牌

<meta name="csrf-token" content="{{csrf_token()}}">

在您的脚本顶部添加 ajaxSetup,这样任何地方都可以访问。这将在每次 ajax 调用时设置 headers

$.ajaxSetup({
    headers: {
        'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
    }
});

<form> 标签上设置令牌

将以下功能添加到您的 <form> 标签。此函数将生成一个名为 _token 的隐藏字段,并用 token

填充值
{{csrf_field()}}

csrf_token() 函数添加到隐藏的 _token 值属性中。这将仅生成加密字符串。

<input type="hidden" name="_token" value="{{csrf_token()}}"/>.


可能的变化 - 2

检查session存储路径和权限

这里假设项目appurl是APP_URL=http://project.dev/ts/toys-store

  1. 设置写权限为storage_path('framework/sessions')
  2. 检查您的 laravel 项目的路径 'path' => '/ts/toys-store', 此路径是您的 laravel 项目的根目录。
  3. 更改您的 cookie 的名称'cookie' => 'toys-store',

    return [
        'driver' => env('SESSION_DRIVER', 'file'),
        'lifetime' => 120,
        'expire_on_close' => false,
        'encrypt' => false,
        'files' => storage_path('framework/sessions'),
        'connection' => null,
        'table' => 'sessions',
        'lottery' => [2, 100],
        'cookie' => 'toys-store',
        'path' => '/ts/toys-store',
        'domain' => null,
        'secure' => false,
        'http_only' => true,
    ];
    

可能的变化 - 3

在 AJAX

上使用 _token 字段

在 AJAX 通话中发送 _token 的方法有很多种

  1. 使用 var formData = new FormData($("#cart-add")[0]);
  2. 获取 <form> 标签内所有输入字段的值
  3. 使用$("#cart-add").serialize();$("#cart-add").serializeArray();
  4. 在 AJAX 的数据上手动添加 _token。使用 $('meta[name="csrf-token"]').attr('content')$('input[name="_token"]').val().
  5. 我们可以像下面的代码一样在特定的 ajax 调用上设置为 header。

    $.ajax({
        url: "path/to/ajax",
        type: "POST",
        data: formData,
        processData: false,
        contentType: false,
        dataType: "json",
        headers: {
            'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
        }
    });