SOLVED: Cannot receive POST-request from JS

$.ajax({
url: ‘http://localhost:8008/ersatzteiltool/remoterender/orderSubmit’,
headers: {
‘X-CSRF-Token’: “<?= json_encode($this->request->getParam('_csrfToken')); ?>”
},
contentType: “application/json; charset=utf-8”,
dataType: “json”,
type: “post”,
data: JSON.stringify(cmd),
}).done(function(response) {
console.log(“POST got THROUGH :)”);
});

Hmm… may I note that your route says /transferData while your ajax call is requesting orderSubmit
Please make sure you are using the right url :stuck_out_tongue:
Or even better, use CakePHP’s url builder (along with the reverse routing capability)!

$.ajax({
  url: `<?= h($this->Url->build(['controller' => 'RemoteRender', 'action' => 'orderSubmit'])); ?>`,
  // ... rest of your ajax stuff
})

https://book.cakephp.org/3.0/en/views/helpers/url.html

1 Like

Interesting Idea! I’ll try it.

Yeah sorry, in the meantime i changed the route in routes.php to:
$routes->connect(’/remoteRender’, [‘controller’ => ‘remoterender’, ‘action’ => ‘index’, ‘orderSubmit’, ‘userRedirect’]);

just trying out different things…

Just make sure that either:

  1. your array in the url builder matches the one in your route
  2. your url matches your scope

Example given:

case 1.:

// config/routes.php
Router::scope('/', function (RouteBuilder $routes) {
  $routes->connect('/myRoute', ['controller' => 'MyController', 'action' => 'index']);
});
// script.js
$.ajax({
  url: `<?= h($this->Url->build(['controller' => 'MyController', 'action' => 'index'])); ?>`,
  // ... rest of the ajax stuff
})

case 2.:

// config/routes.php
Router::scope('/', function (RouteBuilder $routes) {
  $routes->connect('/myRoute', ['controller' => 'MyController', 'action' => 'index']);
});
// script.js
$.ajax({
  url: `/myRoute`,
  // ... rest of the ajax stuff
})

Recommendation:

Use option 1 as this allows you to change the url without changing the route itself.
So let’s say you want to change the /myRoute part to /asdf, you can do so without having to change your views (and thus prevent potential breakage of your app).
The url builder will match the array you’ve given it and spit out the right url!

Try axios js. Remember to add csrfToken to the header. Example.

axios.defaults.headers.common[‘X-CSRF-Token’] = “<?php echo $this->request->getParam('_csrfToken'); ?>”;
axios.defaults.headers.common[‘Cache-Control’] = “no-store, private, no-cache, must-revalidate”;
axios.defaults.headers.common[‘Expires’] = 0;

axios.post(‘your controller/service method/optional pass data’, {data:{key:value data to the server}})
.then(function (response) {//process response

})
.catch(function (error) {//Catch that nasty error from the server

});

Thanks for your help!
Tried FinlayDaG33ks solution and njuejohns with axios, now if i log the error object from a axios request i get:
Error: “Request failed with status code 403”
exports https://unpkg.com/axios/dist/axios.min.js:8
exports https://unpkg.com/axios/dist/axios.min.js:8
onreadystatechange https://unpkg.com/axios/dist/axios.min.js:8
logAjaxRequest http://localhost:8008/debug_kit/js/toolbar.js?1561463013:74

I managed to decode the recevied data from the get-request, problem is, i initally wanted to send some encoded image files, as i know i can’t do that with a get-request because of the limited url size?

Why on earth would you want to upload an image using a GET request :stuck_out_tongue:
We have PUT for that stuff :stuck_out_tongue:
Also, you might want to send the data chunked in order to not hit a POST-size limit randomly…

Yeah as i said, i want to send my images with a POST (PUT would be fine aswell) request, but i really cant get it working with CakePHP.

I don’t want to send data with a get request, thats litterly not what the request is made for,b ut at the moment its the only way i can receive data at all…

What do your logs have to say about the cause of the 403 error? Those don’t typically happen without leaving some details.

I think that if all this stuff doesn’t work, you have something else causing the 403…
What is the output you’re getting?
Like, when I get an error, I get a huge red screen in my face telling me exactly what went wrong…

I think you need to set $this->autoRender to false and $this->layout to false.

Well, probably i should have started with looking into the error.log files…
it says CSRF token mismatch.
In this thread there were some suggestions how to send a valid CSRF header.

I tried so far using ajax:
headers: { 'X-CSRF-Token': <?= json_encode($this->request->getParam('_csrfToken')); ?> }
and axios:

axios.defaults.headers.common[‘X-CSRF-Token’] = “<?php echo $this->request->getParam('_csrfToken'); ?>”;

the log says with both ways CSRF token mismatch.

I added in the Application.php a new CsrfProtectionMiddleware for the middlewareQueue, no changes.

You are using CakePHP 3 right? (maybe I should have asked this earlier).

yeah, my project is setup with 3.7.9

Could you try it using the “incognito” mode of your browser?

Incognito mode: Error Log still says the same.

Tried a chrome plugin(Allow-Control-Allow-Origin: *) which i used when i got CSRF problems locally, but error still remains. :roll_eyes:

If I understand the stack correctly. You are using CakePHP as a backend API whilst connecting it with a front end framework…

You will need CSRF token, which means the page from where you are posting will need a way to get the csrf token before the call begins.

Secondly, Allow control allow origin.
The cors issue can be resolved once you return correct cors response.
https://book.cakephp.org/3.0/en/controllers/request-response.html#setting-cross-origin-request-headers-cors

1 Like

Thanks for your answer! Yeah, you got the stack right.

So what i could do is: send a get request from my frontend to cakePhp requesting the CSRF token and then add the recevied CSRF token to my POST request header?

Exactly!

But the get request must call for the same action which will process the form. Just in-case.

1 Like

Sorry for my late answer, but i didn’t have any time to test it until now.
karmicdice was exactly right and it worked right away, very much thanks to you.