XHR中的缓存无效

时间:2017-07-31 01:06:22

标签: jquery laravel laravel-5.3 laravel-5.4

我正在使用XHR GET获取刀片html并尝试对其进行缓存,以便每次都不需要去服务器下载它。这是我的代码。

但这不起作用,总是去服务器。

$.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() {
    }
});

控制器

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

标题信息

enter image description here

3 个答案:

答案 0 :(得分:3)

实际上这不是jQuery的错。根据文件:

  

cache设置为false只能正常使用HEAD和GET请求。它的工作原理是将"_={timestamp}"附加到GET参数。

因此,它实际上强制浏览器加载所请求资源的新副本,方法是通过更改URL来欺骗它。因此浏览器认为它是一个新请求,然后再次从服务器加载它。 实际上在某处缓存了响应。

缓存响应是浏览器的一部分,要发挥此角色,它需要适当的缓存标头。我可以看到,你的回复中没有包含@elegisandi在评论中指出的合适的标题。因此,这个问题有两种可能的解决方案。

将缓存标头添加到服务器响应

您必须修改响应标头,以便浏览器可以缓存响应。 This question及其答案可以帮助您设置。

手动缓存响应

您可以在JavaScript对象中手动缓存请求的响应。 但要注意,您手动必须使这些到期。以下是如何执行此操作的示例:

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();
});

第二次向同一个URL发出请求时,它实际上会从缓存中返回响应。此外,我们可以自定义ajaxCall函数,以便它也检查请求方法。

答案 1 :(得分:1)

jQuery ajax cache选项(http://api.jquery.com/jquery.ajax/)只控制浏览器是否可以使用正常的缓存策略。它默认为true

要在此实际使用缓存,服务器(您的Laravel应用程序)应该告诉客户端可以缓存返回值。

现在(Cache-Control: no-cache, private)它明确禁止客户端缓存结果。 Cache-Control标头非常通用(请参阅https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control),但您可以返回值Cache-Control: public,告诉客户端资源是公共的,并且可以始终缓存。

您可以在控制器操作中执行此操作,如下所示:

public function SendMessageForm() {
    return response()
               ->view("Chat.SendMessage")
               ->header('Cache-Control', 'public');
}

答案 2 :(得分:1)

您需要更改服务器端的响应行为:

return response()
            ->view('Chat.SendMessage')
            ->header('Cache-Control', 'public, max-age=300');