1.21 gigawatts
1.21 gigawatts

Reputation: 17870

Detect when a page has changed on the filesystem using JavaScript

Is there a way to check if the page has changed when the page is on the local filesystem (file:/// not http:// or https://)?

There are answers here that use AJAX to check the headers for a "Last-Modified" header but this is not returned when using the file protocol.

Here's the headers returned in Firefox when testing locally:

// headers
Content-Type: text/xml
Content-Length: 20941

Update:
It looks like the response is set to the file and that has a lastModified property on response. I've added an answer.

Upvotes: 2

Views: 1486

Answers (4)

1.21 gigawatts
1.21 gigawatts

Reputation: 17870

After some debugging I noticed that the response is set to the file in the response property and that has a lastModified property on it!

Modifiying the code in @bugfroggy's answer this seems to work:

function checkForChanges() {
    var contentDate = null;
    var frequency = 5000;

    setInterval(() => {
        let xmlhttp = new XMLHttpRequest();

        xmlhttp.addEventListener("load", (progressEvent) => {
            console.log("Content loaded()");
            if (contentDate==null) {
                contentDate = xmlhttp.response.lastModified;
                return;
            }

            if(xmlhttp.response.lastModified != contentDate) {
                window.location.reload(true);
            }
        });

        //xmlhttp.open("GET", window.location.href);
        xmlhttp.open("HEAD", window.location.href);
        //xmlhttp.responseType = "blob";
        xmlhttp.send();
    }, frequency);

}

checkForChanges();

Note: I think the code above uses ES5 or ES6 features and I don't know if this will work on a server (http:// or https://).

Upvotes: 1

Jack Bashford
Jack Bashford

Reputation: 44145

What you could do is change the request header from HEAD to GET/POST, which'll return a responseText value. From there, it's very easy to check - have a value before the GET/POST call named original or something similar, compare it to the response, and change stuff if necessary.

Upvotes: 1

robere2
robere2

Reputation: 1716

Based off of your replies in the comments, I would use some form of caching the page.

Check this answer to get the page's current contents as a string and cache it/a hash of it. From there, perform an AJAX request to the current page and compare the contents/hashes. If they do not match, then you can reload the page.

let contents = document.documentElement.outerHTML;
let frequency = 5000; // How often to check for changes (ms)

setInterval(() => {
    let xmlhttp = new XMLHttpRequest();

    xmlhttp.addEventListener("load", (res) => { 
        if(res.responseText != contents)
            window.location.reload(true);
    });

    xmlhttp.open("GET", window.location.href);
    xmlhttp.send();
}, frequency);

Upvotes: 1

Adrian Brand
Adrian Brand

Reputation: 21658

Use a dev webserver that auto reloads on changes, better to test with a web server over serving from the file system anyway.

Upvotes: 0

Related Questions