AppEngine:转发请求到静态内容

时间:2016-03-01 23:05:32

标签: google-app-engine caching http-headers

为了优化缓存,我将时间戳添加到图像的src值等,例如<img src="/static/img/foo.1456871418309.png"/>.

然后我创建了一个servlet过滤器,它再次删除了时间戳,然后将请求转发给资源。 request.getRequestDispatcher (urlWithoutTimestamp).forward(request, response)

appengine-web.xml我指定缓存文件一年。

<static-files>
    <include path="/static/**" expiration="365d" />
</static-files>

这样,我认为,用户总是可以获得最新版本,并且可以将其缓存,直到存在更新的版本,而无需通过HTTP进行测试。

在localhost(运行方式为Web应用程序)上运行正常,HTTP响应具有预期的缓存标头:

Cache-Control:"public, max-age=31536000"
Expires:"Wed, 01 Mar 2017 22:54:32 GMT"

然而,当我在app引擎服务器上部署整个内容时,响应具有此缓存标头(并且没有“Expires”):

Cache-Control:"private"

我还尝试在HttpServletRequestWrapper上调用FilterChain来修改getRequestURI,getRequestURL,getServletPath,而不是转发请求。这导致同样糟糕的结果。

我如何做到这一点?

更新

第二个想法,我认为转发到静态内容可能是不可能的,因为转发总是在服务器本地完成,静态内容可能很好地在另一台机器上提供。

但至少我能用我的过滤器来解决我的HTTP头问题:

  1. 我使用HttpServletRequestWrapper(见上文)从请求中删除时间戳,而不是转发请求。
  2. 然后我在修改后的请求上调用chain.doFilter。
  3. 最后我在响应中设置了缓存标题。

2 个答案:

答案 0 :(得分:1)

在生产中,您将无法拦截静态文件流量。 Google App Engine会为您处理静态文件,基本上提供了一种CDN。

我引用https://cloud.google.com/appengine/docs/java/config/webxml#Filters

上的说明
  

即使路径与a匹配,也不会在静态资源上调用过滤器   过滤映射模式。静态文件直接提供给   浏览器。

答案 1 :(得分:1)

您可以引用实际的静态文件,并将时间戳添加为请求参数,而不是更改文件名和使用过滤器。

而不是:

<img src="/static/img/foo.1456871418309.png"/>

使用以下架构:

<img src="/static/img/foo.png?r=1456871418309"/>

对于静态文件,忽略此类参数。但对于浏览器,它每次都是一个新的URL,因此它将从服务器请求。