I am writing a local html family tree.
Since the site is supposed to contain many personal pages that will take me a long to write, I want my browser to display in grey the links to the pages that have still not been created (everything here is on the server side in the project directory).
It seemed it was only a matter of checking if a file existed and changing the colour of the link with javascript, but it turned out to be much more complicated than I thought. I read several solutions in google to check if a file exists, and all of them failed. One of them is the following:
function LinkCheck(url) {
var http = new XMLHttpRequest();
http.open('HEAD', url, false);
http.send();
return http.status !== 404;
}
This failed. Then I tried to debug, and change the function to:
function LinkCheck(url) {
var http = new XMLHttpRequest();
http.open('HEAD', url, false);
http.send();
//return http.status !== 404;
return false;
}
This should have worked unconditionally since the function returns "false" in any case. But this one failed too.
Then I disabled the "send" part:
function LinkCheck(url) {
var http = new XMLHttpRequest();
http.open('HEAD', url, false);
//http.send();
//return http.status !== 404;
return false;
}
An this worked! So, the problem is the function http.send() that causes a failure. Any insight?
Note: I tried with Firefox and Chrome, with the same results.
EDIT 1:
The JavaScript code that actually uses this function is:
if (LinkCheck("Abraham_page.html")){} else {
document.getElementById("Abraham_link_id").style.color = "gray";
}
Where "Abraham_page.html" may be located inside the same directory as the page containing the calling function (but actually don’t exist).
Edit 2:
I’m not use to the debugger tool, but it seems the relevant message is:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at file:///C:/Tex-Dir/Tex_Work/User/html/genealogy/Abraham_page.html. (Reason: CORS request not http).
2
Answers
In order to return a boolean answer using XMLHttpRequest#send, like you are trying to do in your
LinkCheck
function, you need to first realize that whether you use.onreadystatechange
or.onload
, the return statement will only return from the callback function, and not fromLinkCheck
. In order to be able to pass the server response back to your code, you’d need to pass this function a callback and call it when ready, something along the lines of:and somewhere in your code you’d have:
But then the same problem sort of propagates to the rest of your code and make code messy, hard to read, hard to debug, hard to maintain.
You could try instead using Fetch API, which is based on Promises and can produce somewhat less nested code when used with
async
/await
:Then your code looks much intuitive, much like what you expected from
XMLHttpRequest
.With
fetch
you can also use raw promises with.then()
– but it terms of code nesting this won’t make it any different from what you currently have withXMLHttpRequest
You may want to use
fetch
for that. It’s relatively simple to detect the 404 (not found) error result, throw an error if so and do something to the href in html when it occurs. Here the very handy service from https://httpstat.us/ is used to retrieve errors: