使用查询参数缓存获取的破坏图像

Posted

技术标签:

【中文标题】使用查询参数缓存获取的破坏图像【英文标题】:Cache busting images that are fetched use query params 【发布时间】:2019-11-15 17:08:51 【问题描述】:

我正在使用以下查询参数从 url 源获取图像:

www.server.com/get?img.jpg

但是当服务器更改图像时,由于图像被缓存,我无法获取最新副本。 *** 上的大多数答案都说为缓存破坏添加查询参数,但这在这种情况下不起作用。试过了:

www.server.com/get?img.png&id=1123

有什么想法/建议吗?谢谢

编辑:id= 后面的数字是随机的。

【问题讨论】:

【参考方案1】:

在这种情况下,查询参数暗示总是会改变。如果您只是添加&id=1123,则不会有任何改变。

尝试添加&t=nnnn,其中 nnnn 等于当前时间(以秒为单位)。

或者,如果您在同一台服务器上生成链接,最好使用 nnnn 图像的修改时间(以秒为单位)或时间戳

?img.png&t=2019-07-04.17.03.22

更新

你是这么说的

 http://www.server.com/get?img.png&id=1

 http://www.server.com/get?img.png&id=2

浏览器将其视为相同的图像。我觉得这很难接受,因为它(除其他外)是一个安全漏洞——这意味着,比如说,get?report.pdf&user=whoknows&password=whatever 可能最终会下载get?report.pdf&user=realuser&password=realpassword,而无需第二次提供真实的登录信息。

完全不是说这是你的错(作为一名开发人员,我发现自己经常遇到你的情况),但这里的某个人似乎在某处做得过火了。问题是如何使用您获得的工具和访问权限来确定您在哪里以及可以做什么(如果有的话)。

为什么服务器可能会这样做,最简单的解释是:服务器或它前面的某个缓存系统会剥离额外的参数。因此,您可以随心所欲地询问 id=x273y3 ,该信息永远不会到达服务器并且无法使其执行任何操作。知道它的用例是什么会很有趣。

在某些有限的情况下,您可能会通过一个丑陋的 hack 来完成它 - 如果您请求 12345/../img.png 而不是 img.png,并且路径解析以正确的方式完成,那么缓存层可能不会缓存请求但服务器仍然回复更新的图像。但这是一个脆弱的 hack,因为服务器架构中的许多合法更改最终可能会完全破坏它,导致根本没有图像被发送。

如果您正在与服务器端缓存作斗争,那么您最好尝试添加适当的 no-cache pragmas to the request 本身。许多人使用额外参数 hack 的原因是,由于客户端长期滥用,一些缓存服务器可以并且经常被配置为忽略这些标头。

特别是如果有人做到了参数剥离,他们应该努力正确地支持缓存指令。

(另一方面,如果您的服务器忽略两个合法标头和请求黑客攻击,那么您有一个非常可靠的案例,无论发生什么都在他们头上)。

否则,可能发生的情况是 客户端 认为它可以缓存资源,因为它是通过特定的资源标头(ETag 等)发送的,并且缓存重新验证没有正确完成,因为客户端/服务器不理解,这也经常发生。您应该记录一整套对话并将其发布在此处,以帮助解决问题:

对图像的第一个请求的标头 回复的标题 同时更改的图像的请求标头 回复的标题

它也可以是一些非常简单的东西,例如服务器实际上回复了一个固定的 302,它去除了额外的参数。然后是新的 URL 被缓存:

GET /get?img.png&... 302位置:http://static-images.server.com/images/img.png

这可能是由于 Apache 服务器重写引擎的重写规则过于彻底,例如,“\?(.*.(png|jpg|gif))” 从源请求中获取并重写为“新位置/$1”。在这种情况下,另一个脆弱解决方法是请求/get?img.png?t=12345.png,带有两个?,以欺骗重写引擎捕获img.png?t=12345 而不仅仅是img,因此包括缓存清除。

然而,适当的(如果更长的话)补救措施是让重写人员和缓存人员相互交谈并进行协作,而不是相互冲突。

【讨论】:

您好,感谢您的回复,我输入的数字是随机的,但仍会缓存

以上是关于使用查询参数缓存获取的破坏图像的主要内容,如果未能解决你的问题,请参考以下文章

缓存在 SASS 文件中链接的破坏图像

如何获取缓存图像 SDWebImage 的数据

iOS - 使用 AFNetworking 获取图像保持缓存

MyBatis 查询结果的缓存

使用 shared_from_this 参数等待 std::future 获取 std::async 会阻止对 this 的破坏

如何获取在 Flutter 中使用图像选择器插件选择的图像的原始路径,而不是复制到缓存?