【问题标题】:Force browser to cache some files强制浏览器缓存一些文件
【发布时间】:2014-07-18 23:03:40
【问题描述】:

我在数据库中有很多图像。图像数据存储在带有 id 的二进制列中。我编写了一个 PHP 脚本来读取这些数据并输出正确的 Content-type 和数据。

每当我想在页面上显示图像时,我都会将 /image.php?id=1 放在图像标签的 src 字段中,其中 1 是数据库中图像的 ID。这一切都很好。

现在每次我再次访问该页面或使用 javascript 修改某些图像的 src 时,似乎都会再次从服务器加载该图像。例如,我有一张图片:<img src="/image.php?id=4" />。当我将鼠标悬停在此图像上时,我使用 javascript 将 src 动态更改为 /image.php?id=5。这会导致从服务器再次加载图像,这需要 1 到 3 秒。在文档开头使用像素大小的图像预加载此图像不起作用。我猜这是因为我实际上是在查询一个动态 PHP 脚本。

如果它们具有相同的ID,有什么方法可以让浏览器缓存图像?我的数据库中的图像 ID 很少会改变,如果有的话。

任何帮助将不胜感激。

【问题讨论】:

  • 预加载方法必须有效。
  • 我不相信你可以缓存任何带有“查询参数”的东西
  • 使用路径而不是查询参数(提示:mod_rewrite)并将其用作图像源。
  • 您可能需要发送适当的 HTTP 缓存标头来告诉浏览器缓存图像多长时间。不过,为什么要将图像存储在数据库中?根据我的经验,这是一种糟糕的代码气味。
  • @AlexandruG。你应该把它写成答案,它有效。我从来没想过……

标签: javascript php image caching dynamic-content


【解决方案1】:

文件名仅因查询参数而异的缓存内容不可靠。例如,某些代理服务器会将“style.css?v1”和“style.css?v2”视为同一个文件。这将导致依赖查询参数作为修订号的资产出现意外问题。

在文件名中包含修订

您知道将来会更改的每个资产(主要是css和js),名称或路径中都会包含修订:

  • css/style_v1.css 而不是 css/style.css?v1 (or)
  • css/v1/style.css 而不是 css/style.css?v1

基于文件名的缓存清除

如果您没有适当的构建过程,这种方法将对您有所帮助。您将保持文件名不变(即:style.css),并在 mod_rewrite 的帮助下将请求从 /css/style.<revision>.css 重写为 style.css。

  1. 在您的 HTML 中:

    <link rel="stylesheet" href="css/style.432.css">
    
  2. 然后从 .htaccess 将该请求类型路由到 css/style.css:

    <IfModule mod_rewrite.c>
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteRule ^(.+)\.(\d+)\.(css|cur|gif|ico|jpe?g|js|png|svgz?|webp)$ $1.$3 [L]
    </IfModule>
    
  3. 下次当您更改 style.css 中的某些内容时,您会从 HTML 文件更改您的 css 文件的修订号:

    <link rel="stylesheet" href="css/style.433.css">
    

如果您使用的是 VCS,您甚至可以使用当前提交作为资产的修订号,这将有助于在您的测试阶段发现问题,此时您经常在分支之间切换以测试应用程序的不同方面。

阅读更多:

【讨论】:

  • 好答案。请注意:您的答案似乎集中在如何不让浏览器根据提供的查询参数使用文件的缓存版本,而我想浏览器使用缓存版本。我使用此答案中介绍的原则通过将图像重写为路径而不是查询字符串来使我的浏览器缓存图像。尽管我会提到这一点,以防将来的用户认为这个答案不能回答问题。
猜你喜欢
  • 2023-04-01
  • 2011-10-11
  • 2016-02-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多