Grails:每次 ajax 调用时发送缓存头的最佳方式 [英] Grails: best way to send cache headers with every ajax call

查看:20
本文介绍了Grails:每次 ajax 调用时发送缓存头的最佳方式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

众所周知,Internet Explorer 积极缓存ajax 调用 而所有其他浏览器每次都获取最新的数据.这通常很糟糕:我从未遇到过我希望 ajax 不联系服务器的情况.Firefox、Safari 和其他浏览器知道这一点,并且不会缓存 ajax 调用.

It's well known that Internet Explorer aggressively caches ajax calls whereas all the other browsers grab the data fresh every time. This is usually bad: I've never encountered a case where I want ajax to NOT contact the server. Firefox, Safari and the other browsers know this and don't cache ajax calls.

要防止 IE 缓存,您必须执行以下操作之一:

To prevent IE from caching, you have to do one of the following:

  • 向查询字符串添加缓存破坏令牌(如 ?time=[timestamp])
  • 发送明确禁止 IE 缓存请求的 HTTP 响应头
  • 使用 ajax POST 而不是 GET

我更喜欢设置无缓存标头.这是正确的方法:它告诉所有浏览器不要缓存,这正是您想要的.查询字符串方法用永远不会检索的内容填充浏览器的缓存,为合法缓存内容留下更少的空间.而 POST 方法是对 HTTP 的一种破坏:POST 用于修改数据.

I much prefer setting a no-cache header. It's the correct way: it tells all browsers not to cache, which is exactly what you intend. The query string method fills up the browser's cache with stuff that'll never be retrieved, leaving less room for legitimate cache content. And the POST method is a corruption of HTTP: POSTs are for modifying data.

在 Grails 中,为所有 ajax 请求自动发送 do-not-cache 标头的最佳方法是什么?我不想修改任何控制器,所以我认为必须有一个很酷的过滤技巧或其他东西.

In Grails, what's the best way to automatically send a do-not-cache header for all ajax requests? I don't want to modify any controllers, so I'm thinking there's got to be a cool filter trick or something.

谢谢!

推荐答案

这是我最终想出来的.大多数 javascript 库——包括 jQuery、YUI、Mootools 和 Prototype——在每个 ajax 请求上发送 X-Requested-With: XmlHttpRequest 标头.

Here's what I finally figured out. Most javascript libraries --including jQuery, YUI, Mootools and Prototype -- send the X-Requested-With: XmlHttpRequest header on every ajax request.

对于发送此标头的任何请求,您可以发回一个响应标头,告诉它不要缓存.

For any request that sends this header, you can send a response header back that tells it to not cache.

下面是一个 Grails 过滤器,可防止缓存使用 X-Requested-With: XmlHttpRequest 标头标识自己的 ajax 请求:

Below is a Grails filter that prevents caching of ajax requests that identify themselves with the X-Requested-With: XmlHttpRequest header:

// put this class in grails-app/config/
class AjaxFilters {
    def filters = {
        all(controller:'*', action:'*') {
            before = {
                if (request.getHeader('X-Requested-With')?.equals('XMLHttpRequest')) {
                    response.setHeader('Expires', '-1')
                }
            }
        }
    }
}

有些人更喜欢使用 Cache-Control: no-cache 标头而不是 expires.区别如下:

Some people prefer to use the Cache-Control: no-cache header instead of expires. Here's the difference:

  • 缓存控制:无缓存 - 绝对无缓存
  • 到期:-1 - 浏览器通常"通过条件 If-Modified-Since 请求联系 Web 服务器以更新该页面.但是,该页面保留在磁盘缓存中,并在不联系远程 Web 服务器的适当情况下使用,例如当使用后退"和前进"按钮访问导航历史记录或浏览器处于离线模式时.
  • Cache-Control: no-cache - absolutely NO caching
  • Expires: -1 - the browser "usually" contacts the Web server for updates to that page via a conditional If-Modified-Since request. However, the page remains in the disk cache and is used in appropriate situations without contacting the remote Web server, such as when the BACK and FORWARD buttons are used to access the navigation history or when the browser is in offline mode.

通过添加此过滤器,您可以使 Internet Explorer 的缓存与 Firefox 和 Safari 已经做的保持一致.

By adding this filter, you make Internet Explorer's caching consistent with what Firefox and Safari already do.

顺便说一句,我在 IE8 和 IE9 上遇到过缓存问题.我认为 IE7 和 IE6 也存在这个问题.

BTW, I've experienced the caching problem on IE8 and IE9. I assume the problem existed for IE7 and IE6 as well.

这篇关于Grails:每次 ajax 调用时发送缓存头的最佳方式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆