Abhishek Kumar
Abhishek Kumar

Reputation: 2286

Http Post in laravel using fetch api giving TokenMismatchException

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

      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 :

$.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

enter image description here

Fetch api call headers

enter image description here

Upvotes: 24

Views: 38152

Answers (7)

Gilberto P&#233;rez
Gilberto P&#233;rez

Reputation: 41

Token

let csrfToken = document.head.querySelector('meta[name="csrf-token"]');
document.getElementById('_id').addEventListener('change',(e)=>{
    fetch('/method',{
        method : 'POST',
        body: JSON.stringify({text : e.target.value}),
        headers:{
            'Content-Type': 'application/json',
            "X-CSRF-Token": csrfToken.content
        }
    }).then(response =>{
        return response.json()
    }).then( data =>{


    }).catch(error =>console.error(error));
})

Upvotes: 4

Abhishek Kumar
Abhishek Kumar

Reputation: 2286

I was able to make it work.

There were 2 changes I have to make

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

credentials: "same-origin"

2)the data need to be submitted in Form data format rather than 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){


         });

Upvotes: 19

Bemtorres
Bemtorres

Reputation: 21

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

    }

Upvotes: 1

umutyerebakmaz
umutyerebakmaz

Reputation: 1037

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

Upvotes: 14

Similoluwa Oluwatomi
Similoluwa Oluwatomi

Reputation: 474

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

Upvotes: 32

GONG
GONG

Reputation: 4026

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

Upvotes: 0

Ken Seah
Ken Seah

Reputation: 21

If you are using Form, remember to add

<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.

And change _token to csrf-token as mentioned by GONG

Upvotes: 1

Related Questions