Grails:每次调用ajax时发送缓存头的最佳方法

Dea*_*ses 12 ajax grails internet-explorer caching

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

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

  • 在查询字符串中添加缓存清除令牌(如?time=[timestamp])
  • 发送HTTP响应头,专门禁止IE缓存请求
  • 使用ajax POST而不是GET

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

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

谢谢!

Dea*_*ses 19

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

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

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

// 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')
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

  • 缓存控制:无缓存 - 绝对没有缓存
  • 过期:-1 - 浏览器"通常"通过条件If-Modified-Since请求与Web服务器联系以获取对该页面的更新.但是,页面保留在磁盘缓存中,并在适当的情况下使用,而不联系远程Web服务器,例如,当使用BACK和FORWARD按钮访问导航历史记录或浏览器处于脱机模式时.

通过添加此过滤器,您可以使Internet Explorer的缓存与Firefox和Safari已经执行的操作一致.

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

  • 您还可以使用if(request.xhr)来确定您的请求是否通过AJAX. (2认同)