1

I found a code that could get the last modified time of a file on the server and have adapted it to my needs, it works fine but I get the warning below and reading about the code seems to be resource intensive for the users computer.
The code needs to react (reload) to a file being modified and print out the time since it was last modified.
I notice my computer is (slightly) sluggish when I have two windows open that use this code, perhaps this is the reason.

What can I do to make this asynchronous?

Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/ .

       <script>
            var pageload = new Date();
            function fetchHeader(url, wch) {
                try {
                    var req=new XMLHttpRequest();
                    req.open("HEAD", url, false);
                    req.send(null);
                    if(req.status== 200){
                        return req.getResponseHeader(wch);
                    }
                    else return false;
                } catch(er) {
                    return er.message;
                }
            }

            window.setInterval(function(){
                var time = Date.parse(fetchHeader("Akut.txt",'Last-Modified'));
                var d = new Date();
                var diffSec = Math.round((d - time) / 1000);
                document.getElementById("time").innerHTML = Math.trunc(diffSec/60) + " minutes"; // time since it was modified
                
                if ((d-pageload)/1000 > 10 && diffSec < 5 ){
                    location.reload();
                }
            }, 2500);
        </script>

I found this thread XMLHttpRequest is deprecated. What to use instead? and I have tried to modify the code but I can't get this code to give me the last modified time.
This just returns NaN.


             function fetchHeader(url, wch) {
                try {
                    var xhr = new XMLHttpRequest()
                    xhr.onreadystatechange = function() {
                        if (this.readyState === this.DONE) {
                            console.log(this.getResponseHeader(wch)); // assumed this would work but it doesn't
                        }
                    }
                    xhr.open("HEAD", url)
                    xhr.send()
                } catch(er) {
                    return er.message;
                }
            }

I need help with making this asynchronous. I have tried to read the xhr link from the warning but I'm not much of a Javascript developer so it's hard for me to find what I need to do.
Can someone point me in the right direction here?

Andreas
  • 23,610
  • 6
  • 30
  • 62
  • 1
    Do you have to support some older browsers? If not, then please have a look at the "new" `fetch` API https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API You will find many examples for how to use it online. It is async by default and works with promises which allows you to use async / await. – Eddi May 17 '23 at 11:01
  • I believe the browsers used is some old version of IE. I'll have to look this up first. Thanks! – Andreas May 17 '23 at 11:51

1 Answers1

1

Here is the async xmlhttp request

const pageload = new Date(); // when the page loaded
const url = "Akut.txt";
const whichHeader = "Last-Modified";
const compareTimeToNow = (time) => {
  let d = new Date();
  let diffSec = Math.round((d - time) / 1000);
  document.getElementById("time").textContent = Math.trunc(diffSec / 60) + " minutes"; // time since it was modified
  if ((d - pageload) / 1000 > 10 && diffSec < 5) location.reload();
  else setTimeout(getHeader, 2500)
};

const getHeader = () => {
  const req = new XMLHttpRequest();
  req.addEventListener("load", reqListener);
  req.open("HEAD", url);
  req.send();
};

function reqListener() {
  console.log(this.responseText);
  compareTimeToNow(new Date(this.getResponseHeader(whichHeader)).getTime());
}
getHeader();

Using fetch (Chrome 42+, Edge 14+, Safari 10.1+ Firefox 39+ and Opera 29+ - no IE)

const pageload = new Date(); // when the page loaded
const url = "Akut.txt";
const whichHeader = "Last-Modified";
const compareTimeToNow = (time) => {
  let d = new Date();
  let diffSec = Math.round((d - time) / 1000);
  document.getElementById("time").textContent = Math.trunc(diffSec / 60) + " minutes"; // time since it was modified
  if ((d - pageload) / 1000 > 10 && diffSec < 5) location.reload();
  else setTimeout(getHeader, 2500)
};

const getHeader = () => {
  fetch(url)
  .then(rsp => compareTimeToNow(new Date(rsp.headers.get(whichHeader)).getTime());
};

getHeader();
mplungjan
  • 169,008
  • 28
  • 173
  • 236
  • 1
    I tested the xml code since I believe I can't run fetch (Eddis comment above) on the old computers. The message is gone so it seems to work. Thank you! – Andreas May 17 '23 at 12:03
  • What is an older browser? Fetch is supported on Chrome 42+, Edge 14+, Safari 10.1+ Firefoxx 39+ and Opera 29+ - so not on IE but that is about it – mplungjan May 17 '23 at 12:07
  • 1
    And I'm quite sure it's IE 9 - something these computers have. It's computers that are built to just display a webpage and by some reason they opted for IE as the browser on them. – Andreas May 17 '23 at 12:53
  • One question. If I want to make the code react to two files last modified time. Do I add a `url2` and copy paste the "content" of `getHeader` so that I have a `req2`? – Andreas May 19 '23 at 08:05