Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Caching in XHR is not working

I am fetching blade html using XHR GET and trying to cache it so that it does not need to go to server to download it every time. Here is my code.

But this does not work and always goes to server.

$.ajax({
    method: "GET",
    url:    "{!! route('SendMessageForm') !!}",
    cache:  true,
    async:  true,
    beforeSend: function(xhr, opts) {
        $('#MessageModal').html(processingImageUrl);
    },
    success: function(result) {
        $('#MessageModal').html(result);
        PopulateActiveUsers();
    },
    error: function() {
    }
});

Controller

public function SendMessageForm() {
    return View("Chat.SendMessage");
}

Header Info

enter image description here

like image 395
Pankaj Avatar asked Jul 31 '17 01:07

Pankaj


People also ask

Are XHR requests cached?

XHR responses are cached automatically in the browser cache if your HTTP cache headers permit it.

How HTTP caching works?

The HTTP cache stores a response associated with a request and reuses the stored response for subsequent requests. There are several advantages to reusability. First, since there is no need to deliver the request to the origin server, then the closer the client and cache are, the faster the response will be.

Are HTTP headers cached?

Cache-Control is a HTTP cache header that contains a set of parameters to define the browser's caching policies in the client requests and server responses. When a client makes a request to the server, the browser can cache, or store copies of resources for faster access and lower latency.

Where is HTTP cache stored?

The HTTP Cache is the module that receives HTTP(S) requests and decides when and how to fetch data from the Disk Cache or from the network. The cache lives in the browser process, as part of the network stack.


1 Answers

It is not the fault of jQuery actually. Per the documentation:

Setting cache to false will only work correctly with HEAD and GET requests. It works by appending "_={timestamp}" to the GET parameters.

So, it actually forces browser to load new copy of the requested resource, by tricking it by changing the URL. So browser thinks that it is a new request, and then loads it from the server again. It doesn't actually caches the response somewhere.

Caching the responses is browser's part, and to play this role, it needs appropriate cache headers. I can see, your response doesn't contain appropriate headers as pointed out by @elegisandi in the comments. So there are two possible solutions to this problem.

Add cache headers to server response

You will have to modify the response headers, so that the browser can cache the response. This question and its answers can help you setting up that.

Manually cache the response

You can manually cache the response of the requests in a JavaScript object. But beware, you'll manually have to expire these. Here is an example of how to do this:

var cache = {};

function ajaxCall(options) {
  if (!cache[options.url]) {
    cache[options.url] = $.ajax(options);
  }

  return cache[options.url];
}

// In your code
ajaxCall({
  method: "GET",
  url: "{!! route('SendMessageForm') !!}",
  beforeSend: function (xhr, opts) {
    $('#MessageModal').html(processingImageUrl);
  }
})
.then(function (result) {
  $('#MessageModal').html(result);
  PopulateActiveUsers();
});

The second time you fire a request to the same URL, it will actually return the response from the cache. Further, we can customise the ajaxCall function so that it checks the request method as well.

like image 167
31piy Avatar answered Oct 20 '22 02:10

31piy