我正在处理一个特别昂贵的(在查询和带宽方面),把它想象成一个项目目录。然而,目录还需要在任何时候都完全准确,即对目录的更新需要实时反映,因此固定的缓存过期时间将不起作用。
客户端正在使用JQuery 1.8.2请求目录,如下所示:
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "http://myserver.com/somejsonquery.aspx",
data: {},
dataType: "json",
success: function ( ... ) { ... },
error: function ( ... ) { ... }
});
结果是内容类型为"application/JSON "的正确格式化JSON。
因为我在服务器端维护一个可靠的缓存,我真的很想实现if - modified -Since语义,这样我的服务器可以在缓存是当前的时候返回304(不引起DB或网络命中),并且只有在"if - modified -Since"时间戳发生重新加载时才向客户端发送新目录。
然而,我有麻烦让这个工作(至少在IE上)。我尝试设置以下内容,但仍然无法让客户端发送If-Modified-Since:
- 在JSON请求中设置"cache: true"
- 让服务器在响应中返回"Cache-control: private" HTTP报头
有人对此有什么见解吗?
作为后续,我也想知道如果我设置缓存控制为"公共"(即可由代理服务器缓存),缓存的一致性仍然会通过代理维护吗?也就是说,每次客户端请求该页面时,代理都会检查回我的服务器。如果我要启用代理缓存,我需要完全确定代理将保证一致的缓存状态。
我被困在这个问题上有一段时间了,所以任何帮助都会很感激!
谢谢,- k .
使缓存头等跨浏览器兼容并不是一门精确的科学。如果你不介意受到网络攻击,试试这个。
1)附加一个唯一的id到您的目录,并将其发送到客户端,并在ajax请求中返回它。
2)测试该唯一ID是否与缓存目录的最新版本匹配。如果是,则返回304响应代码,否则返回新目录以及新的惟一ID。
我终于弄明白了。结果我需要做以下更改:
客户端jQuery:- 使用"GET"而不是"POST"在我的AJAX调用。似乎不应该缓存的帖子和正确的。 忘记在AJAX调用中设置"cache: true"——如果你想使用浏览器缓存,这是无关紧要的。只有当你想滚动你自己的客户端缓存系统时,它才重要。
- 总是发送最后修改头
- 总是发送"Cache-control: private, max-age=1"
- 检查来自客户端的"if - modified - since"报头,如果没有修改,返回304,没有有效载荷,否则返回200,结果集
使用上面的逻辑,我将浏览器缓存设置为1秒后过期,并将依赖于服务器权威地决定是否需要使用适当的304代码返回新目录。似乎在IE上工作得很好。
请注意Brad上面关于苹果手机浏览器行为不端的评论。因为只有一小部分用户会使用苹果移动设备,所以我决定保留浏览器缓存,因为它的好处实在是太令人难以置信了,但我尝试在特殊情况下,只对苹果移动浏览器强制"无缓存"。