My REST endpoint is set up like:
'foo/bar'=>[
'GET'=>[
'controller'=>$fooController,
'action'=>'baz'
],
'POST'=>[
'controller'=>$fooController,
'action'=>'barSave'
]
],
and my jquery (3.6.0.min.js) $.post() is...
$.post({
url: '/foo/bar',
data: data,
success: function(data, status, jqXHR){
alert('Post successful');
},
error: function (jqXHR, status){
alert('Post failed: ' + jqXHR.responseText)
},
dataType: "JSON"
});
The jqXHR.responseText I get is essentially "undefined index POST" in my entrypoint, on the line: $controller = $routes[$this->route][$this->method]['controller']; $this->method is just set as $_SERVER['REQUEST_METHOD']
Seems like there is some gap between $.post and $_SERVER['REQUEST_METHOD'], but can't figure out why. My router/entrypoint works for all other "vanilla" form posts, just not this one jquery one.
Every discussion on the internet uses a file.php endpoint as the url, so absolutely no hints out there. jquery $.post documentation and jquery ajax settings page didn't offer any insights either. Any help much appreciated...
////UPDATE/////////////////////////
In response to comments, here are some excerpts from my routing code :
from index.php:
$route = ltrim(strtok($_SERVER['REQUEST_URI'), /'?'), '/')
$method = $_SERVER['REQUEST_METHOD'];
$entrypoint = new \Entrypoint($route, new \Routes(), $method);
$entrypoint->enter();
The Routes() constructor, creates a set of new models and saves each as a class var. Routes() also has method getRoutes(), which creates new controllers using those models saved as class vars, defines/returns my $routes[] array (with uri pairs formed as 'controller/action' pairs and defined as shown above with the actual $controller objects).
Entrypoint->enter() then just validates & saves the uri to $this->route, re-authenticates the user, and sets the $controller and $action accordingly via:
$controller = $routes[$this->route][$this->method]['controller'];
$action = $routes[$this->route][$this->method]['action'];
then creates a new $view, and calls $view->output($model). That's pretty much it. Vanilla and reliable for several past projects, no issues.
Then I used jquery's $.post for the first time last week to test an idea, and unexpected stuff started happening immediately. Strange requests from jquery -- requests to /foo/bar that failed, requests to /foo/foo/bar that were succeeding, requests triggering 303's (I don't have any 303s set up), bad requests not returning my router's 404 as usual, etc), then all requests stopped appearing in the Chrome network tool altogether. I thought maybe it was a cache problem, but emptying didn't change anything. I was still getting jqXHR.responseText from failures allowing me to get $.post() working consistently by moving the action to the current page's controller, so I chalked it up to REST routing triggering some unexplained fallback. My frontend knowledge is admittedly basic but I can usually get stuff to work how i want it to without a problem. This is my first time using jquery, though. I was definitely specifying '/foo/bar' not foo/bar' as the url (I even tried an absolute url using var absUrl = window.location.origin+"/foo/bar".
I would love to understand what is going on, but the more I think about it, the less any of it makes sense.
Figured out what was going on, so to potentially save others time, answering my own Q. It boils down to misleading jquery variable naming and documentation.
The "url" parameter inside $.post{} may act like "a string containing the URL to which the request is sent" in most cases, but a REST router shows it isn't one.
Instead of
"url" : "/foo/bar"routing my request as POST->foo->bar(), it was always sending it toPOST->currentPage->bar. In other words, "url" is not a request url, but simply an "action" tag for an invisible form.I have confirmed this by moving
public function bar(){}into the current controller and using"url" : "/currentpage/bar", and simply"url" : "bar()". Interestingly, even"url" : "/lkajsdhfklashd/bar"works, so I assume there is some fallback that only looks at what comes after the last/if it can't find what it is looking for at a specified url.