How to Make Laravel AJAX POST Requests Using Vanilla JavaScript

AJAX allows web applications to send and receive data from a server asynchronously without reloading the page. While jQuery is commonly used for AJAX requests, modern JavaScript (ES6+) provides built-in methods like fetch() to handle AJAX. In this article, we’ll show you how to make an AJAX POST request in Laravel using only vanilla JavaScript.

Why Use AJAX in Laravel?

AJAX is essential for creating dynamic, fast, and user-friendly web applications. Some benefits include:

  • Sending data to the server without a full page reload.
  • Updating parts of a page dynamically.
  • Improving user experience by making the app more interactive.

We’ll walk through how to implement an AJAX POST request using Laravel and vanilla JavaScript.

Set Up Laravel Routes

First, define the route where your AJAX POST request will be sent. In routes/web.php, add the following:

use App\Http\Controllers\AjaxController;

Route::post('/ajax-request', [AjaxController::class, 'store'])->name('ajax.request');

This route listens for a POST request at /ajax-request and directs it to the store method of AjaxController.

Create the Controller

Next, you’ll need to create the AjaxController to handle the POST request:

php artisan make:controller AjaxController

Open the newly created controller and add the store method:

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class AjaxController extends Controller
{
    public function store(Request $request)
    {
        // Validate incoming data
        $request->validate([
            'name' => 'required|string|max:255',
            'email' => 'required|email',
        ]);

        // Process the data (e.g., store in the database)
        $name = $request->name;
        $email = $request->email;

        // Return a JSON response
        return response()->json(['success' => 'Data successfully saved!', 'name' => $name, 'email' => $email]);
    }
}

In this method, we validate the request data, process it, and return a JSON response back to the client.

Build the Blade Template with Vanilla JavaScript

Next, create a Blade view (resources/views/ajax-form.blade.php) that contains a form and handles the AJAX POST request using vanilla JavaScript:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Laravel AJAX POST with Vanilla JavaScript</title>
</head>
<body>
    <h1>Submit Form Using Vanilla JavaScript AJAX POST Request</h1>

    <form id="ajax-form">
        @csrf <!-- Important for Laravel security -->
        <label for="name">Name:</label>
        <input type="text" id="name" name="name"><br><br>

        <label for="email">Email:</label>
        <input type="email" id="email" name="email"><br><br>

        <button type="submit">Submit</button>
    </form>

    <p id="success-message" style="color: green; display: none;"></p>

    <script>
        document.getElementById('ajax-form').addEventListener('submit', async function(e) {
            e.preventDefault();

            // Prepare form data
            const formData = new FormData(this);

            // CSRF token (important for Laravel)
            const csrfToken = document.querySelector('input[name="_token"]').value;

            // Send AJAX POST request using fetch
            try {
                const response = await fetch('{{ route('ajax.request') }}', {
                    method: 'POST',
                    headers: {
                        'X-CSRF-TOKEN': csrfToken,
                        'Accept': 'application/json'
                    },
                    body: formData
                });

                if (response.ok) {
                    const data = await response.json();
                    document.getElementById('success-message').textContent = data.success;
                    document.getElementById('success-message').style.display = 'block';
                } else {
                    // Handle server validation errors
                    const errorData = await response.json();
                    alert('Error: ' + (errorData.errors.name || errorData.errors.email));
                }
            } catch (error) {
                // Handle other errors (e.g., network issues)
                alert('An error occurred: ' + error.message);
            }
        });
    </script>
</body>
</html>

In this code:

  • The form is submitted via a submit event listener.
  • FormData is used to serialize the form inputs and send them in the AJAX request.
  • fetch() is the modern way to send an AJAX request using vanilla JavaScript.
  • We include the X-CSRF-TOKEN header, which is required by Laravel to prevent cross-site request forgery.

Handling Validation Errors

If the server returns a validation error (HTTP status code 422), Laravel will send back error messages in JSON format. You can handle this in the JavaScript code like this:

if (!response.ok && response.status === 422) {
    const errorData = await response.json();
    alert('Validation Error: ' + (errorData.errors.name || errorData.errors.email));
}

This block checks if the status code is 422, indicating a validation error, and then displays the error message to the user.

Testing the AJAX POST Request

Now, start your Laravel development server:

php artisan serve

Visit http://127.0.0.1:8000/ajax-form, fill out the form, and submit it. If everything is working correctly, you should see the success message without a page reload.

See Also: