发送XMLHttpRequest时缓存结果出现问题?

4
我对AJAX和缓存的概念都不太了解。
在W3Schools的AJAX - Send a Request To a Server页面上,它说应该在要运行的脚本的URL末尾添加 "?t=" + Math.random() 来防止缓存。
在维基百科上,“cache”的简单定义是:
“在计算机科学中,高速缓存是一个组件,它透明地存储数据,以便未来请求该数据时可以更快地响应。存储在高速缓存中的数据可能是已经计算过的值或者是存储在其他地方的原始值的副本。”
但是,这样做会更好吗?如果计算机已经存储了一些重复的数据,脚本会运行得更快。另外,在教程页面上的第一个示例没有添加到URL,也可以正常工作。
请问有人能告诉我使用"?t=" + Math.random()的原因吗?

1
缓存是好的,但前提是你请求的页面没有改变。比如你请求一个stackoverflow问题页面,如果浏览器加载了缓存版本,你就看不到自上次查看以来新增的任何答案。?t=参数只用于这种情况。如果你知道数据没有/不会改变,那么就不要使用?t= - Mike Edwards
2
"?t=random"被称为缓存破坏。然而,对于正确利用缓存控制的服务器来说,这可能只会导致不必要的网络使用。不要仅仅因为这个原因而这样做。(另外,尽量避免使用w3schools..) - user2864740
3个回答

7

但是,这样不是更好吗?

是的,出于性能原因最好使用缓存系统,因为应用程序页面将快速加载,因为已经加载过一次的元素将被检索而无需每次向服务器发出HTTP请求。

有人能告诉我使用 "?t=" + Math.random() 的原因吗?

添加 "?t=" + Math.random() 就像每次重新加载脚本的 URL。即使没有任何实际变化,缓存系统也会将其视为新元素而不是已经存储的旧元素。所以它强制从服务器重新加载元素。

通常,我们可能希望在频繁更新的元素(如图像、脚本)上执行此操作。例如,在网站上更改个人资料图片时,如果旧图片文件在缓存中,如果我们不使用随机数技巧,用户将无法立即看到新图片。用户可能认为他上传的图片未起作用。他必须手动清空浏览器中的缓存,这并不总是非常直观。

第二个原因可能是在开发过程中这么做很好,因为我们不需要每分钟都清空缓存来考虑我们的代码更改......

但是,在您确定不会更改或很少更改的元素上不要使用此技巧。


1
通常我在历史上看到缓存失效处理时,它是通过“debug”标志进行控制的(这样可以在非开发环境中禁用它)。然而,现在具有良好开发工具的浏览器允许我们“禁用所有缓存”,这在我看来是一个更好的开发解决方案。 - user2864740

1
添加一些随机元素到网络服务请求的结尾是因为在很多情况下您想要数据总是最新的。如果您对它进行缓存,那么数据可能就不是最新的。例如,假设您有一个AJAX请求,它会给您当前游戏的高分。您使用http://example.com/get_high_score.php进行调用。假设它返回100。现在,假设您等待了5秒钟并再次调用它(或者用户刷新了页面)。如果该请求被缓存了,则可能会再次返回100。然而,在此期间,得分可能已经变为125。如果您调用http://example.com/get_high_score.php?t=12345786,那么得分将是最新值,因为它没有被缓存。 url + "?t=" + Math.random()只是其中一种方法。我更喜欢使用时间戳,因为它保证始终唯一。url + "?t=" + (new Date()).getTime()
在另一方面,如果你不需要数据始终保持最新(例如,你只是发送一个菜单选项列表,这些选项几乎永远不会更改),那么缓存是可以的,并且你想要省略额外的部分。

0

另一个选择是使用时间戳,或设计一个每几秒钟更改一次的时间戳。虽然最好的方法(如果可以)是在服务器响应的头部添加条目,告诉浏览器不要缓存结果。

var t = new Date().getTime(); var t2 = Math.floor(t/10000); url = target_url + "?t=" + t2;

虽然在这种情况下不太可能发生,但请注意,如果您的站点不断生成指向随机内部URL的链接(例如通过服务器端代码),则会成为“蜘蛛陷阱”,搜索引擎等爬虫会被卡住,不断地跟随这些随机链接周围,导致服务器负载增加。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接