laravel 中的 Http Post 使用 fetch api 给出 TokenMismatchException

Posted

技术标签:

【中文标题】laravel 中的 Http Post 使用 fetch api 给出 TokenMismatchException【英文标题】:Http Post in laravel using fetch api giving TokenMismatchException 【发布时间】:2016-11-06 21:11:10 【问题描述】:

我正在尝试使用 fetch api 发布 http 帖子。即使我正在发送令牌,我也会收到错误 TokenMismatchException in VerifyCsrfToken.php 。如何使用 fetch api 拨打电话? (我也尝试过使用 jQuery ajax 并且它工作得很好)继承 fetch api 代码

      var URL = $("#form").attr("action");
      var token = $("input[name='_token']").val();
      var group_id = $(this).val();
  fetch(URL, 
       method: 'post',
       mode: 'no-cors',
       body: JSON.stringify(
           'csrf-token': token,
           'group_id': group_id
       )
     ).then(function(response)
           return response.json();
       )  .then(function(json)



       )
         .catch(function(error)


         );

我已经以这样的形式添加了令牌

<form id="form" action=" url('api/getcoursebygroup') ">
    <input type="hidden" name="_token" id="csrf-token" value=" Session::token() " />
  </form>

这个 jQuery ajax 调用工作正常:

$.ajax(
          type: "POST",
          url:  URL,
          data:  "group_id" : group_id, "_token" : token ,
          dataType: 'json'
      ).done(function (result) 

        if(result.code == 1)



        


      );

jQuery ajax 调用头文件

获取 api 调用标头

【问题讨论】:

哪个 laravel 版本?对于 5.*,它应该是 csrf-token 而不是 _token hm...你能在开发工具中比较两个请求的 xhr 吗? 当我进行 jquery ajax 调用时,它使用 _token 而不是 csrf-token 我正在使用 laravel 5.2 对不起,这是我的错。我把它和meta 名字混淆了 【参考方案1】:

如果你使用的是Form,记得添加

<input type="hidden" name="_token" id="csrf-token" value=" Session::token() " />

或者如果使用刀片按钮:

 Form::token() 

在任何地方(通常是主体顶部)添加它就足以满足所有 javascript 驱动的按钮。如果您使用刀片生成表单,这是自动添加的,所以不必这样做。

如 GONG 所说,将 _token 更改为 csrf-token

【讨论】:

当我进行 jquery ajax 调用时,它使用 _token 而不是 csrf-token 我正在使用 laravel 5.2【参考方案2】:

经过一番研究,以下是应该为您解决的问题:

var myHeaders = new Headers(
  "X-CSRF-TOKEN": $("input[name='_token']").val()
);

var URL = $("#form").attr("action");
  var token = $("input[name='_token']").val();
  var myInit = 
   method: 'post',
   headers: myHeaders,
   mode: 'no-cors',
   body: JSON.stringify(
       'group_id': group_id
   ;
  var group_id = $(this).val();
  fetch(URL, myInit)
)
.then(function(response)
       return response.json();
)  .then(function(json)



)
.catch(function(error)


);

如果你有 Chrome ,它也不会工作

【讨论】:

@AbhishekKumar 立即尝试,已修复,这是因为异步。至少我现在可以在我的 plunkr 中看到标题 x-csrf-token 。你可以在这里看到它:plnkr.co/edit/aTBrcb0QLqlPwVudCm2T?p=preview【参考方案3】:

我能够让它工作。

我必须进行 2 项更改

1) Fetch Api 默认不使用cookie。所以为了让它使用我添加的cookie

credentials: "same-origin"

2)数据需要以Form数据格式提交,而不是json格式

这是我的工作代码

       var URL = $("#form").attr("action");
       var token = $("input[name='_token']").val();
       var group_id = $(this).val();

      fetch(URL, 
       method: 'post',
       credentials: "same-origin",
       body: new FormData(document.getElementById('form'))
     ).then(function(response)
           return response.json();
       )  .then(function(json)

         // change course

       )
         .catch(function(error)


         );

【讨论】:

声明的令牌在哪里使用?【参考方案4】:

我可能会迟到,但这也可以

    fetch("/audio/signed", 
      headers: 
        "Content-Type": "application/json",
        "Accept": "application/json",
        "X-Requested-With": "XMLHttpRequest",
        "X-CSRF-Token": $('input[name="_token"]').val()
      ,
      method: "post",
      credentials: "same-origin",
      body: JSON.stringify(
        key: "value"
      )
    )

【讨论】:

你节省了我的时间! 这是救命稻草。谢谢。【参考方案5】:

index.blade.php

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

app.js

const csrfToken = document.head.querySelector("[name~=csrf-token][content]").content;

function orderPost(order) 
    fetch('/orders', 
        method: 'post',
        body: JSON.stringify(order),
        headers: 
            'Content-Type': 'application/json',
            "X-CSRF-Token": csrfToken
        
    )
    .then(response => 
        return response.text();
    )
    .then(text => 
        return console.log(text);
    )
    .catch(error => console.error(error));
;

OrderController.php

public function store(Request $request)
    $order = new Order();
    $order->user_id = $request->json('user_id');
    $order->item_list = $request->json('item_list');
    $order->leave_note = $request->json('leave_note');
    $order->total = $request->json('total');
    $order->save();

    $response = [
        'status' => 'success',
        'message' => 'order stored',
];

    return response()->json($response);


【讨论】:

你好@umutyerebakmaz。如何在您的方法中实施验证? 你好 Maik,你应该做两种验证,在我看来,第一种是前面的 javascript,另一种是传统的 laravel 表单请求验证。这是对 JavaScript 所做的改造,但 Laravel 所做的是必须做的。这就是你可以做到的。它在 laravel 文档中,但你仍然可以像这样快速入门。 laravel.com/docs/8.x/validation#creating-form-requests 但我的示例中的方式是不同的解决方案,我认为我们应该询问如何以不同的方式验证 request->json。 你好@umutyerebakmaz。谢谢您的回答。是的,我的意思是如何验证 json 对象。我还没有尝试过,但我可以想象一个json的内容没有经过验证。【参考方案6】:
function post(id)

        const token = ' csrf_token() ';
        web = "request()->getHttpHost()" ;
        url = 'http://' + web + '/metodo';

        fetch(url, 
            method: 'post',
            credentials: "same-origin",
            headers: 
                'Content-Type': 'application/json',
                "X-CSRF-Token": token
            ,
            body: JSON.stringify(
                key: id
            )
            ).then(response => 
                return response.json();
            ).then(text => 
                return console.log(text);
            ).catch(error => console.error(error));

    

【讨论】:

以上是关于laravel 中的 Http Post 使用 fetch api 给出 TokenMismatchException的主要内容,如果未能解决你的问题,请参考以下文章

通过 angular http post 将 json 数据发送到 laravel 控制器

(axios) HTTP POST 请求两分钟后失败,Laravel 5 + VueJS

Vuejs Axios POST 请求从 Laravel 后端获取 HTTP422 错误

在 laravel 中使用错误的 http 请求类型(例如 get 而不是 post)时返回 404

Laravel POST 路由返回 HTTP 代码 200 但没有创建记录

Laravel - 使用对象数组更新并将记录保存到数据库