2

在我们的应用程序中,我们有两个用例,我们希望避免从浏览器缓存中检索过时的图像:

  1. 用户更改了她的个人资料图片。
  2. 一个用户改变了她被允许管理的另一个用户的图片(想想一个团队和他们的队长)。

在上传视图中,通过在图像 URL 上附加时间戳没有任何问题,正如其他问题(AJAX 文件上传后刷新图像中断图像缓存)中所建议的那样。对于所有其他视图,这种简单方法可能存在问题:我们实际上希望尽可能使用缓存,但如果我们知道我们最近更新了图像,请避免使用它。

在我们的应用程序中,管理用户使用用户列表,该用户列表通过用户图像表示用户(我知道,这是革命性的)。如果她刚刚更改了其中一个用户图像,她希望此列表显示新图像。每隔一次她看到用户的图像时也是如此。

我们不能添加?timestamp={now}到此用户列表中的每个图像,因为这会破坏任何缓存的好处。

对于尽可能多地使用缓存并重新加载我们知道我们已经更新的图像的好方法有什么建议吗?

4

1 回答 1

0

我们目前选择的解决方案:

  1. 我们计划为图像设置适当的标题(请参阅这个非常好的答案
  2. 我们存储在渲染 URL 时使用的更新图像的本地列表

第 2 部分可能需要一些解释:幸运的是,我们在前端使用了一个非常好的 JS 框架,它允许我们定义任意方法并在模板中使用它们。我们的模型有一个返回照片 URL 的方法,这个 URL 用于每个模板。

上传新图片时,我们将 id 与 localStorage 中的当前时间戳关联:

window.localStorage['nocache.'+id] = new Date().getTime()

每当我们请求图像路径时,我们都会查看 localStorage 以查看是否必须将时间戳附加到 URL,否则 URL 会按原样返回。

优点/改进

  • 用户自己触发的更新将立即可用,不仅在缓存过期后。
  • 所有其他资源都使用缓存。
  • 我们会查看localStorage我们正在构建的每个图像 URL。这可能很昂贵。
  • 我们总是必须通过模型的方法来创建照片 URL(从 DRY 的角度来看很好,但我们必须使用模型)

代码

生成 URL 的代码如下所示

getPhotoUrl: function() {
    return api.getImageUrl(this.id)
}

在 API 中(非常简化)

getImageUrl: function(id) {
    var url = "/prefix/something/user/" + id + "/image";
    // if we have stored a timestamp, add that to the URL
    var noCache = window.localStorage['nocache.'+id];
    if (noCache !== undefined) {
        url += "?" + noCache;
    }
    return url;
}

模板代码保持不变:

<!-- render via img.src -->
<img src="<%= user.getPhotoUrl() %>" alt="<%= user.lastname %>" />

<!-- render via CSS background -->
<div class="img" alt="<%= this.shortUsername %>"
    style="background-image: url('<%= this.getPhotoUrl() %>')">
    ...
</div>
于 2012-07-17T13:18:07.717 回答