0

I have some JavaScript that sends an XMLHttpRequest() to a PHP file every minute to fetch some JSON data, and then display it.

The first time this runs, after 1 minute, I get the "Success!" in the browser Console, and a request was made to /data.php in the Network tab.

But subsequent times, I get "Success!", but with the same data (including the same time), and the Network tab shows no further requests were made to /data.php

const url = "/data.php";

setInterval(refreshData, 60000);

var refreshData = function () {
  var xhr = new XMLHttpRequest();

  xhr.onreadystatechange = function () {
    // Only run if the request is complete
    if (xhr.readyState !== 4) return

    if (xhr.status >= 200 && xhr.status < 300) {
      console.log("Success!", xhr);
      displayData(JSON.parse(xhr["responseText"]));
    } else {
      console.error("Error fetching data");
    }
  };

  xhr.open("GET", url);
  xhr.send();
};

Here's data.php:

header('Content-type: application/json;charset=utf-8');
$data = array(
    "foo" => "bar",
    "time" => time(),
);
echo json_encode($data);

I can solve this by adding a cache-busting "?" + new Date().getTime() to the url called by the JS.

Or by doing this in the PHP:

header('Cache-Control: no-cache, no-store, must-revalidate');
header('Pragma: no-cache');
header('Expires: 0');

So I could use one of those solutions, but they smell a bit bad. I've tried this:

$seconds_to_cache = 1;
header("Cache-Control: max-age=$seconds_to_cache");
header("Pragma: cache");
$expire_time = gmdate("D, d M Y H:i:s", time() + $seconds_to_cache) . " GMT";
header("Expires: $expire_time");

but it doesn't have any effect. What am I missing?

Phil Gyford
  • 13,432
  • 14
  • 81
  • 143
  • you can add cache control into the xhr request - https://stackoverflow.com/a/48969579/1772933 – Kinglish Jun 16 '21 at 11:51
  • 1
    Hello, before answering to the hole question, there is something that i did not understand when you said `and the Network tab shows no request was actually made to /data.php` , instead i tried your JS code (without data.php) and i decreased the setIntervalTime to `500` , so that the requests are executed normally without any problem.. so i want to know, what if you test your JS with another php file ? – sohaieb azaiez Jun 16 '21 at 11:55
  • @Kinglish Thanks. I've just tried adding `xhr.setRequestHeader("Cache-Control", "no-cache, no-store, max-age=0");`, and then the "Expires" and "Pragma" headers too, but with no effect unfortunately. – Phil Gyford Jun 16 '21 at 13:04
  • @sohaiebazaiez Thanks for trying! I'm not sure what the purpose is of trying with a different PHP file. Why would that be different? And I clarified that sentence in my question - the Network tab only shows the first request to `data.php`. – Phil Gyford Jun 16 '21 at 13:05
  • If you load data.php in a browser window and hit soft reload does it update correctly? – James Jun 16 '21 at 13:07
  • @James Yes it does - I can refresh it every second and the "time" value increases. – Phil Gyford Jun 16 '21 at 13:13
  • "I can solve this by adding a cache-busting "?" + new Date().getTime() to the url called by the JS." - this is pretty standard, I don't see why it "smells bad"... – Joe Jun 16 '21 at 13:13
  • @Joe I may end up doing this. I just felt that the question of whether to cache, and how long for, should maybe be done by the server, ideally. – Phil Gyford Jun 16 '21 at 13:23
  • I'd say take a look at all the headers on the response from the server (to the request to `/data.php`) to see whether any other cache affecting headers are added by the hosting server software. – msbit Jun 17 '21 at 02:01

1 Answers1

0

I am currently looking into XMLHttpRequest() myself. Noticed the topic is almost two years old already, but maybe it's still useful to someone coming across this.

W3Schools has something that might be relevant to your issue: https://www.w3schools.com/xml/ajax_xmlhttprequest_send.asp

GET or POST?

GET is simpler and faster than POST, and can be used in most cases.

However, always use POST requests when:

  • A cached file is not an option (update a file or database on the server).
  • Sending a large amount of data to the server (POST has no size limitations).
  • Sending user input (which can contain unknown characters), POST is more robust and secure than GET.

Sounds to me you are running into some caching issues. Give the POST method a spin and see if that works. Hope that helps!

Baddy
  • 1