Reaction of DataTables server-side on a 302 from server
Reaction of DataTables server-side on a 302 from server
I am experimenting with a Docker-based solution that runs a PHP application over FrankenPHP. FrankenPHP uses Caddy internally as a server.
Unlike Apache, Caddy will often respond to the AJAX request for server-side data by a 302 or 303 redirect, immediately followed by the correct JSON with server-side data. Nevertheless, DataTables doesn't take kindly to the redirect and triggers the error
https://datatables.net/manual/tech-notes/7
indicating that it didn't follow through with the redirect, but ended up in the error handler.
Unfortunately, I cannot link to any test case, given that this is a code under heavy development and not ready to be deployed publicly yet. But I wonder if DT could be made to react to 302/303 redirects gracefully.
This question has an accepted answers - jump to answer
Answers
Looks like Datatables starts with this base Ajax config:
Datatables uses jQuery ajax() to fetch the data. I suspect there is an HTTP error in the response causing the
error
handler to be called. Theajax
docs state that you can override theajax
options exceptsuccess
. Possibly you can override theerror
object to diagnose the error. See the jQuery ajax() docs for the parameters passed into theerror
function.Let us know what you find.
Kevin
Also I would try using
curl
to determine if the error is caused by something Datatables is doing.Kevin
So, I added the following error code to my ajax definition:
and the output is as attached.
I can see the communication in my Developer Tools. The server sends a 303 and the browser replies immediately to this redirect, receiving a well-formed definition of (empty) data set to draw:
It seems to me that my original diagnosis was correct: Caddy, for some reason, replies with a redirect to the original AJAX request from DataTables and DataTables expects a 2xx response instead.
I only don't know why Caddy is doing that. My experience with Caddy as a HTTP server is about three days in total. I used to work with Apache for decades, but Caddy is new to me. I would abandon it instead of trying to solve that, but the trouble is, in my specific situation, its performance is much better than Apache's.
@allan can comment on whether Datatables checks the status code or other checks before throwing the Ajax error. But this example shows a 301 redirect works:
https://live.datatables.net/socirone/1/edit
And this server side processing example shows a 307 redirect works:
https://live.datatables.net/yaroyala/1/edit
This leads me to believe, maybe incorrectly, that Datatables doesn't just only expect 2xx resposnes.
Did you try using
curl
? Or possibly jQuery ajax()? You may need to passdraw: 1
as a parameter for your server side processing script.I don't have a way to generate 302 or 303 responses to test with. Might need to wait for Allan to respond if you don't find the same issue with curl.
Kevin
What precisely should I try with Curl? I can do it, but I don't know where to begin.
The intriguing part is that this piece of web code has been under development since May 2022. For about 900 days, under Apache, I have literally never seen this behavior ever, on multiple test servers, Docker or not-Docker.
But once I started fiddling with FrankenPHP / Caddy on this Friday, hey presto, it happens all the time.
I'm not familiar with caddy but possibly this is causing the redirect?
https://caddyserver.com/docs/caddyfile/directives/redir
Kevin
Well, it doesn't look like that, my Caddyfile is extremely simple. I suspect it has something to do with the total amount of workers in that FrankenPHP instance.
The 302 behavior doesn't start immediately after bootup of the container, only after a few request/response pairs. And it started happening more frequently when I reduced the total amount of workers to 8.
Might be a caching problem, too.
Sorry I can't help more as I don't have a way to generate 302 or 303 responses. @allan will need to comment if the ajax error is due specifically to these status codes.
Maybe Stack OVerflow or the Caddy community can help debug why Caddy is sending the redirects. If the behavior of the web server changes as time goes on then maybe this is the problem that needs to be solved.
Kevin
I will try to put some example online... and I will ask at the Caddy community too.
Can you show me the request URL and also the 302 redirect response from the server (ideally all of the headers, but just the
Location
one will do if needed.There are some cases whereby a 302 won't be followed by the browser for Ajax - e.g. from an https source being redirected to an http one. That should show as an error on the browser's console I would think.
I'm a little confused as to why some requests to the URL would result in 302, and some wouldn't (presumably resulting in a 200 OK?). Is it the same URL you are requesting? If it gives a 302, where is it sending you - perhaps doing some kind of load balancing?
Allan
I will try to put a working example online today or tomorrow. I am now just waiting for someone else to prepare a working Docker server for me, and they promised to do this today.
So, I was able to set up a working example, but I have to send you, @allan, a username/password combo. That application isn't prepared for anonymous use, unfortunately.
I sent it to you through a message.
I think you have a misconfiguration of the Caddy web server. Both 301 Moved Permanently and 302 Found require a location header to indicate the URL to redirect to. Here is a 301 response ( I tried to change all domain and IP addresses info ):
I don't see a
location
header. I don't see one in the 302 response either. It should look something like this:The browser is not able to follow the redirect because the
location
header does not exist. Possibly there is a misconfig causing the 302 response when there shouldn't be a 301 or 302. Or the config issue is with adding thelocation
header. I didn't find anything useful regarding Caddy and the missinglocation
header.Kevin
See the Redirections in HTTP for info of how they work.
Kevin
Take a look at the browser's network inspector for this example I posted before:
https://live.datatables.net/socirone/1/edit
It has a 301 Moved Permanently response. In the response headers you can see the
location
header is present:Kevin
Thank you for your analysis. Certainly looks weird. I will try to produce some samples using curl and submit them to a Caddy discussion.
Looking into the problem in more detail, it looks like a subtle bug in my worker code, where a Dependency Injection Container doesn't get fully re-set between requests.
Responses like 301 or 302 or 303 shouldn't contain a body, but here, a 3xx response comes with the actual JSON body.
It is very obviously not a DataTables problem, not really even a Caddy problem, but a DI problem. The framework I am using is not yet fully capable of resetting containers. Thank you for leading me to the correct root of the problem.
Thanks for letting us know. Good luck tracking it down.
Allan