【问题标题】:Play Framework and caching of images播放框架和图像缓存
【发布时间】:2011-12-21 02:08:51
【问题描述】:

我的模板中有一些这样的代码:

#{list people, as:'person'}
    <img src="@@{Application.image(person.id)}">
#{/list}

启动播放服务器后,列表会多次显示第一张图像。例如,如果 people 变量包含 1、2、3、4、5 的 id - 那么将显示五张图像,但它们都是相同的图像:对应于 1 的 id 的图像。

如果我点击刷新,图像都会根据它们的 ID 改变为唯一的。从模板渲染的 html 如下所示:

<img src="http://url/application/image?personId=1"/>
<img src="http://url/application/image?personId=2"/>
<img src="http://url/application/image?personId=3"/>
<img src="http://url/application/image?personId=4"/>
<img src="http://url/application/image?personId=5"/>

如何阻止模板第一次显示相同的图像?

编辑:还尝试在响应 src 请求的控制器中的 renderBinary(image) 调用之前添加下面看到的响应标头:

...
response.setHeader("Pragma-directive", "no-cache");
response.setHeader("Cache-directive", "no-cache");
response.setHeader("Cache-control", "no-cache");
response.setHeader("Pragma", "no-cache");
response.setHeader("Expires", "0");
renderBinary(imageFile);

根据this 帖子。它实际上在前几次有效,但在停止并启动 Play 服务器后第三次,我遇到了相同的缓存问题,尽管 personId 不同,但所有图像都显示相同的图像。我还没有任何运气将时间戳附加到网址的末尾。

编辑 #2:我还尝试在 application.conf 中将 http.cacheControl 属性更改为 0:

http.cacheControl=0

但它再次给了我不一致的结果,它是否显示了正确或错误的图像。

【问题讨论】:

    标签: java caching playframework


    【解决方案1】:

    我能想到的2个选项:

    1. 生成一个唯一编号,并将其作为无用参数附加到图像的 URL 中。例如,“http://url/application/image?personId=1&ts=12314125123”。由于每次生成页面时都会更改 URL,因此浏览器不会命中缓存并且每次都会请求图像。通常时间戳作为参数效果最好。

    2. 在提供图像时,想办法将“Cache-Control”HTTP 响应标头参数设置为“no-cache”。如果您使用自定义 servlet 流式传输图像,这应该很容易。如果没有,我不确定您如何做到这一点,但也许 Play 提供了一种方法。

    过去,我通常使用选项 1,因为它几乎总是更容易。贫民区,但它有效。

    【讨论】:

    • 我想过这样做,但认为 personIds 至少在第一轮中是唯一的,为什么添加时间戳会有所不同? (我试过了,问题似乎已经消失了,但是对于为什么 personId 没有相同的影响,至少在第一次时有点困惑)
    • 更正,我刚刚有另一个实例,尽管有时间戳,但图像会重复自身。
    • 我也试过这个:response.setHeader("Cache-Control", "no-cache");在调用 renderBinary(image) 之前在我的控制器中;这似乎也没有解决问题。
    【解决方案2】:

    我不确定这是否是一个可行的解决方案,但我现在有一个解决方法,通过做这些事情似乎可以工作(好吧,它还没有对我失败):

    • 在控制器中调用 renderBinary(...) 之前设置缓存控制

      response.setHeader("Cache-Control", "no-cache");

    • 将要渲染的文件转换为 FileInputStream 并将其传递给 renderBinary(...) 方法,而不是直接传递给 File。

    像这样:

    File fileImage = ... // some .png image
    FileInputStream stream = new FileInputStream(fileImage);
    renderBinary(stream);
    

    我从看到这个关于缓存和渲染二进制文件的 bug report 得到这个想法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-27
      • 1970-01-01
      • 1970-01-01
      • 2011-09-30
      • 2011-08-16
      • 2011-12-15
      相关资源
      最近更新 更多