Sending POST Requests with CSRF Protection in Laravel 11 using JavaScript
Last update: 06-12-2024
When working with Laravel 11, it's not easy to find up to date information regarding how to send a POST request with CSRF protection using JavaScript's fetch API.
While adding @csrf
to an HTML form is straightforward, sending a POST request directly from JavaScript requires a different approach. This guide will walk you through the process.
Introduction to CSRF Protection in Laravel
Laravel includes CSRF protection by default. Any request that modifies server state must include a CSRF token to ensure the request is legitimate. For form submissions, you can simply use @csrf
in your Blade template. However, for AJAX requests or other non-form submissions, you need to manually include the CSRF token.
Including the CSRF Token in JavaScript Requests
The most straightforward way to include the CSRF token in a JavaScript request is to send it in the request body. This method eliminates the need to modify request headers extensively. Below is an example of how to do this.
Example Implementation
Let's start by setting up a simple Laravel route and view. We'll create a route to display our view and another to handle the POST request.
web.php
<?php
use Illuminate\Support\Facades\Route;
use Illuminate\Http\Request;
Route::get('/', function () {
return view('welcome');
});
Route::post('/post-endpoint', function (Request $request) {
\Log::info($request->all());
return ['Received data' => $request->moreData];
});
Next, let's create the Blade template that will include our JavaScript code to send the POST request.
welcome.blade.php
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Laravel</title>
</head>
<body>
<button id="post-btn">Send post request</button>
<script>
const submitButton = document.getElementById('post-btn');
submitButton.onclick = function () {
fetch('/post-endpoint', {
headers: {
"Content-Type": "application/json",
},
method: "post",
body: JSON.stringify({
_token: '{{ csrf_token() }}',
moreData: "Some additional data"
})
}).then(function (response) {
return response.json()
})
.then(function (data) {
console.log(data);
})
.catch(function (error) {
console.log('error');
})
}
</script>
</body>
</html>
Explanation
In the welcome.blade.php
file, we have a button with an ID of post-btn
. When this button is clicked, it triggers a JavaScript function that sends a POST request to the /post-endpoint
URL. The request includes the CSRF token and additional data in the request body, formatted as JSON. We also set the Content-Type
header to application/json
to indicate that we are sending JSON data.
On the server side, the route defined in web.php
logs the received data and returns a response containing part of the received data.
Conclusion
By following the above steps, you can easily send POST requests with CSRF protection using JavaScript in Laravel 11. Including the CSRF token in the request body is a simple and effective method to ensure your requests are secure.