How to fixed 419 unknown status in XMLHttpRequest?

I have an error in my XMLHttpRequest() when sending a post request to my url. When I check my console.log it says

this line of code:
xhr.send();

Error: Failed to load resource: the server responded with a status of 419 (unknown status)

Here’s my script code using only pure javascript:

<!-- Get Parameters for gclid or token when user visits the website -->
<script>
    window.onload = function() {
        try {
            var url_string = (window.location.href).toLowerCase();
            var url = new URL(url_string);
            // Get Gclid
            var token = url.searchParams.get("gclid");
    
            // gclid expires in 6 hours
            document.cookie = `gclid=${gclid}; max-age=21600`;
    
            // Sending a get request to laravel controller
            var base_url = window.location.origin; // get the base url
            var params = "gclid=" + gclid;
    
            let xhr = new XMLHttpRequest();
            xhr.open("POST", base_url+"/storetrackvisit?"+params, true);
            xhr.send();
    
        } catch (err) {
            console.log("Issues with Parsing URL Parameter's - " + err);
        }
    }
    </script>

I’m trying to pass parameters in this XMLHttpRequest() so that when users has this parameters.

Example: https://www.test.com/?gclid=312

It will send a post request to my storetrackvisit page along with the parameters and save it to db: https://www.test.com/storetrackvisit?gclid=312

            let xhr = new XMLHttpRequest();
            xhr.open("POST", base_url+"/storetrackvisit?"+params, true);
            xhr.send();

so that it will save to my controller like this:

TrafficController

public function storeParams(Request $request)
{
    $traffic = new TrafficTracking();

    if ($request->has('gclid')) { // check if key = gclid
        $traffic->traffic_type = 'gclid'; // store the key in db
        $traffic->traffic_value = $request->gclid;
    }

    if ($traffic->value === null) {
        return response()->noContent();
    }

    $traffic->ip_address = $request->ip();
    $traffic->domain = $request->getHttpHost();
    $traffic->save();
}

web.php

// Traffic Controller
Route::post('/storetrackvisit', 'TrafficController@storeParams')->name('user.store.trackvisit');

What seems to be an error in my xhr.send(); returning a status of 419 (unknown status)? Is it because there is no csrf token passed along with my XMLHttpRequest in javascript? If so, how do I pass it in the XMLHttpRequest or maybe what’s causing the 419 (unkown status)?

Answer

Usually a 419 Error means a missing CSRF token from a request. You can handle it easily in two ways.

  1. Change the route to GET if you’re not sending any sensitive info.
  2. Include a CSRF token in your request.

I will explain about point number 2, how can you include a CSRF token in your request.

Now, there are also two ways to include a CSRF token:

  1. Call it in header.
  2. Create a HTML input field containing token.

1. Call it in Headers

You can define CSRF token in your header like this,

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

and then access it in JavaScript and set headers for it like this,

xhr.setRequestHeader(header, value);

2. Create a HTML input field containing token

You can create an input field containg token like this,

<!-- It's a laravel blade directive, which creates an input field containing token -->
@csrf

<!-- or manually do it -->
<input type="hidden" name="_token" value="{{ csrf_token() }}">

Get it in your JavaScript and send it as a parameter like this,

let csrfToken = document.getElementsByName("_token");
    
params += "&_token=" + csrfToken;