If neither request is successful I don’t have to do anything, but the user doesn’t see any errors unless they choose to take a look in the browser console.
This all worked wonderfully until I enabled SSL on the page that needs to run these tests, then it immediately fell apart.
Both requests fail, because a page served over HTTPS is blocked from asynchronously fetching content over an insecure connection. Which makes sense, but really throws a spanner into the works for me: neither my home nor corporate intranet sites are available outside the confines of their safe networks, so neither support HTTPS.
My first attempt at getting around this was to simply change the URL prefix for each from http:// to https:// and see what happened. Neither site supports that protocol, but is the error that comes back different for a site which exists but can’t respond, vs. a site which doesn’t exist? It appears so!
We are getting closer to the solution I landed on, however. The next thing I tried was specifying the port in the URL. I used the https:// prefix to avoid the “mixed content” error, but appended :80 after the hostname to specify a port that the server was actually listening on.
This was what I was looking for. Neither server is capable of responding to a HTTPS request on port 80, but the server that doesn’t exist immediately returns an error (with a status code of 0 and the generic “error” as the descriptive text), but the server that is accessible simply doesn’t respond. Eventually the request times out with a status code of 0 but a status description, crucially, of “timeout.”
It’s not a perfect solution. I set the timeout limit in my code to five seconds, which means a “successful” result can’t possibly come back in less time than that. I’d like to reduce that time, but when I originally had it set at 2.5 seconds I was occasionally getting a false-positive on my corporate network caused by, y’know, an actual timeout from a request that took longer than that to return in an error state.
Nevertheless if you have a use-case like mine and you need to test whether a server exists from the client perspective (i.e. the response from doing the check server-side is irrelevant), I know of no other way. As for me, I’m still on the lookout for a more elegant design. I’m next going to try and figure out a reliable way to identify if the user is connected to my home or corporate network based on their IP address. That way I can do a quick server-side check and return an immediate result.
It’s good to have this to fall back on, though, and for now at least it appears to be working.