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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/38196522/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 14:05:57  来源:igfitidea点击:

Http Post in laravel using fetch api giving TokenMismatchException

javascriptjquerylaravelfetch-api

提问by Abhishek Kumar

I am trying to make a http post using fetch api. Even though I am sending the token, I am getting error TokenMismatchException in VerifyCsrfToken.php. How can I make the call using fetch api? (I also tried with jQuery ajax and its working perfectly) Heres the fetch api code

我正在尝试使用 fetch api 制作一个 http 帖子。尽管我正在发送令牌,但我在 VerifyCsrfToken.php 中收到错误TokenMismatchException。如何使用 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){


         });

I have added token in form like this

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

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

This jQuery ajax call is working fine :

这个 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 call headers

jQuery ajax 调用标头

enter image description here

在此处输入图片说明

Fetch api call headers

获取 api 调用标头

enter image description here

在此处输入图片说明

回答by Abhishek Kumar

I was able to make it work.

我能够让它发挥作用。

There were 2 changes I have to make

我必须进行 2 项更改

1) Fetch Api don't use cookie by default. So to make it use cookie I added

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

credentials: "same-origin"

credentials: "same-origin"

2)the data need to be submitted in Form data format rather than json

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

so here's my working code

所以这是我的工作代码

       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){


         });

回答by Similoluwa Oluwatomi

I may be late to the party but this works too

我可能会迟到,但这也有效

    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"
      })
    })

回答by Umut Yerebakmaz

index.blade.php

index.blade.php

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

app.js

应用程序.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

订单控制器.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);
}

回答by Bemtorres

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));

    }

回答by GONG

After some research, here is what should do a trick for you:

经过一些研究,以下是应该为您做的一个技巧:

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){


});

Also it will not work if you have Chrome < 41

如果你的 Chrome < 41,它也不会工作

回答by Ken Seah

If you are using Form, remember to add

如果你使用Form,记得添加

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

or if using blade buttons:

或者如果使用刀片按钮:

{{ Form::token() }}

Adding this anywhere (usually top of body) will be sufficient for all your JavaScript driven buttons. If you are using blade to generate the form, this is automatically added, so don't have to do this.

将它添加到任何地方(通常是身体顶部)对于所有 JavaScript 驱动的按钮就足够了。如果您使用刀片生成表单,则会自动添加此内容,因此不必执行此操作。

And change _tokento csrf-tokenas mentioned by GONG

并更改_tokencsrf-token龚如提及