Search code examples
javascriptajaxlaravelaxiosmiddleware

$request->ajax() returns false on ajax call


I am making a ajax request with axios to a laravel controller, i want to use a middleware to check if the request was made with ajax, but the problem is that when i make an ajax request, the middleware throws false always.

i make the call like this

axios.post('/api/contact/send', {
    ...
    data : data
}).then((response) => {
    Do somethings
}).catch(err => {
    Do somethings
})

my api routes

Route::namespace('Home')->middleware('IsAjaxRequest')->domain(env('HOST'))->group(function(){
    ....
    Route::post('contact/send','ContactController@postContact');
});

the IsAjaxRequest middleware

if(!$request->ajax()) {
    abort(403, 'Unauthorized action.');
}
return $next($request);

and the controller

<?php

namespace App\Http\Controllers\Home;

use Illuminate\Http\Request;
use App\Events\Home\ContactMail;
use App\Http\Controllers\Controller;

use App\Http\Requests\ContactRequest;
class ContactController extends Controller
{
    //
    public function postContact(ContactRequest $request)
    {

        $data  = $request->all();
        event(new ContactMail($request->all()));
        return response()->json();
    }
}

if i take out the middleware, everything will work fine, the problem is when i check $request->ajax() that return false, i have checked it outside the middleware directly in the controlelr but the result is the same, what's wrong? why return false if the call was made via ajax?


Solution

  • Axios does not send the X-Requested-With header that Laravel looks for to determine if the request is AJAX.

    If you ask me you should not use or rely on this header at all but (I guess) for the purposes of easy migration away from jQuery (which does include the header) the basic Laravel boilerplate bootstrap.js has code:

    window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
    

    which ensures all requests made with Axios get this header, however if you are not using that file you need to run this line in your own script.