Javascript 何时实际需要基于文件名的浏览器缓存破坏?

Javascript 何时实际需要基于文件名的浏览器缓存破坏?,javascript,css,caching,header,Javascript,Css,Caching,Header,目前,我们正在使用一种方法以类似于SE的方式破坏浏览器缓存资源,如css和js: 无论如何,在对HTTP头进行了一些测试之后,我想知道什么时候确实需要这样做。这仅仅是90年代遗留下来的东西,还是现代浏览器无法读取上次修改的或ETags HTTP头 缓存问题 当您试图为易失性的JS或CSS提供服务器,并且您不想/不能(例如,使用CDN)依赖HTTP缓存指令头使浏览器请求新文件时。一些旧浏览器不响应HTTP缓存指令;因此,如果你瞄准他们,你的选择是有限的。一些代理服务器剥离、失效或忽略代理信息,因为

目前,我们正在使用一种方法以类似于SE的方式破坏浏览器缓存资源,如css和js:


无论如何,在对HTTP头进行了一些测试之后,我想知道什么时候确实需要这样做。这仅仅是90年代遗留下来的东西,还是现代浏览器无法读取上次修改的或ETags HTTP头

缓存问题

当您试图为易失性的JS或CSS提供服务器,并且您不想/不能(例如,使用CDN)依赖HTTP缓存指令头使浏览器请求新文件时。一些旧浏览器不响应HTTP缓存指令;因此,如果你瞄准他们,你的选择是有限的。一些代理服务器剥离、失效或忽略代理信息,因为它们有缺陷,或者充当攻击性缓存。因此,使用HTTP缓存控制头将不起作用。在这种情况下,您只需确保最终用户在达到F5之前不会获得奇怪的功能

易失性JS/CSS资源可以来自可通过管理/配置面板编辑的文件/资源。其中的一些原因是主题化、布局编辑或国际化的语言定义文件

HTTP 1.0

有一些遗留系统在使用它。考虑到Oracle内置的HTTP服务器(EGP网关)在RDBMS解决方案中仍然使用它。一些代理将1.1请求转换为1.0。古老的浏览器仍然只支持1.0,但现在这应该是一个相对不存在的问题

不管是什么情况,HTTP 1.0使用了一组不同的控制机制,与HTTP 1.1的产品相比,这些机制是“原始的”。它们包括很多启发测试,RFC中没有指定这些测试来让缓存正常工作。在这两种情况下,缓存通常会导致奇怪的行为,因为交付的是过时的内容,或者相同的内容是没有更改的请求

关于pragma的一个注:无缓存

只处理请求,不处理响应;一件人们不知道的普通事情。这是为了防止中间系统缓存敏感信息。它在HTTP 1.1中仍然具有向后支持,但不应使用,因为它已被弃用

…除非微软说IE不会这么做:

输入生成的内容

另一个原因是基于输入参数生成的JS或CSS。仅仅因为URL包含
somefile.js
,并不意味着它必须是文件系统中的真实文件。它可能只是进程输出的JS。若该进程需要根据参数输出不同的内容,那个么获取参数是实现这一点的好方法

考虑页面版本控制。在大型应用程序中,页面可能因历史或业务需求而保留,它允许相同的命名资源存在,但如果需要特定版本,可以根据需要提供。您可以将每个版本保存在不同的文件中,也可以创建一个流程,通过正确的版本更改输出正确的内容

旧浏览器问题

在IE6中,AJAX请求将受浏览器缓存的约束。如果您正在请求一个无法控制的服务,并且URL没有改变,那么向URL添加一个简单的随机字符串可以避免这个问题

浏览器缓存选项

如果我们考虑HTTP 1.1上的RFC,我们也会看到这一点:

许多用户代理使用户可以覆盖基本代理 缓存机制。例如,用户代理可能允许用户 指定缓存的实体(即使是显式过时的实体)是 从未验证过。或者用户代理可能习惯性地添加“缓存”- 控制:每个请求的最大过期时间为3600“。用户代理不应 默认为非透明行为或结果行为 在异常无效的缓存中,但可以显式配置 通过用户的显式操作来实现

更改资源版本控制的URL可以被视为解决此类问题的一种对策。你是否相信这是值得的,我将留给读者

结论

有理由向文件请求中添加GET参数,但实际上,现在这样做的唯一原因(从2012年开始编写)是为动态生成的脚本提供输入参数,并克服无法控制缓存头的问题


就我个人而言,我只用于为动态输出初始化脚本的脚本提供输入参数,但与开发中的所有东西一样,总是有一些边缘情况会增加原因。

当您的数据被推送到CDN时,它确实很有用,并且很难使大型,数据更改时的分布式缓存。这是一个比Josh的+1更好的答案。我发现它在处理CloudFlare时最有用。找到了一个不尊重缓存的浏览器列表()Internet Explorer版本6-8;FireFox版本1.5-3.0;Safari版本3;歌剧9部;