Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

michaeldzjap's avatar

403 errors with RESTful methods using AJAX on shared host

I am trying to deploy a Laravel project on a shared hosting space running apache. The following problem occurs only for the website running on the shared host, on my localhost environment (using nginx to serve my site) everything runs without any errors.

So fwith regards to the site running on the shared hosting: the problem I am running into is that for some reason any 'DELETE', 'PUT' etc. requests using AJAX result in a 403 forbidden error. If I use a normal form submit instead of the AJAX call, every request seems to be handled just fine.

So for deleting, I use the following AJAX snippet:

...
$.ajax({
    method: 'DELETE,
    url: path/to/my/controller,
    headers: {
        'X-CSRF-TOKEN': token
    },
    ...
});
...

which, as said before, is working fine on my local setup, but results in a 403 error on my shared host. Hence, I am relatively sure it can't have anything to do with not passing in the token or not doing any method spoofing.

One thing to mention is that on my shared hosting I have installed my Laravel app in the private_html/test directory and I have copied the content of the Laravel public folder to the public_html/test folder on the hosting server and I have adjusted the two paths in the index.php accordingly. This seems to work, since I can visit and browse the different pages of the site just fine.

I am beginning to suspect that I might need to add/revise the .htaccess file in the public Laravel folder somehow, but I wouldn't know how. Is there anyone who has faced a similar issue?

0 likes
7 replies
Snapey's avatar

how are you resolving the URL to call and have you viewed source on your ajax code to see what URL it is calling?

michaeldzjap's avatar

I'm using a link with it href attribute set to a named route:

 <a href="{{ route('account.project.destroy', $project->id) }}" class="project-delete">delete</a>

And then in my javascript (jquery) I have a click handler which calls the $.ajax function, setting its url argument to the value of the href property. Seems to produce the right url from looking at the error being thrown in the console:

DELETE http://www.mydomain.com/test/account/project/21 403 (Forbidden)

Also checked what url jQuery actually used for the request by logging the result from adding a beforeSend call to my $.ajax:

beforeSend: function (jqXHR, settings) {
    url = settings.url + "?" + settings.data;
 }

which produces:

http://www.mydomain.com/test/account/project/21?_method=DELETE&_token=oJNmJBVwmKhdzXVsF01mnOTwJp5eGuUADLRUYEeM

So that all seems fine...

Snapey's avatar

by the way, you can see XHR requests in the network tools part of the browser developer tools.

Snapey's avatar

have you checked your routes with php artisan route:list

michaeldzjap's avatar

by the way, you can see XHR requests in the network tools part of the browser developer tools.

I know, that's giving me a

Forbidden

You don't have permission to access /test/account/project/21 on this server.

My routes look fine as far as I can tell. As I said before, this is all working fine on my localhost using exactly the same routes and AJAX calls, but using nginx as the server. It just doesn't seem to work on my shared hosting (running apache) for some reason...

michaeldzjap's avatar
michaeldzjap
OP
Best Answer
Level 1

So I figured it out in the end. Still absolutely no idea why it worked perfectly fine on my localhost and not on the shared hosting, but all I needed to do in the end was to change my AJAX call from

$.ajax({
    method: 'DELETE',
    data: { _method: 'DELETE, _token: token },
    ...
});

to

$.ajax({
    method: 'POST',
    data: { _method: 'DELETE, _token: token },
    ...
});
Anddo's avatar

I know there are limitations with this on some servers like IIS and such requests types should be enabled to be accepted. But I had no idea this is the reason on apache servers on shared hosts.

Now even when adding the method to be POST, the request still DELETE !!

Edit: Nope, all good. It was typo, solution works. Thx for sharing michaeldzjap

Please or to participate in this conversation.