【问题标题】:AppEngine: forwarding request to static-contentAppEngine:将请求转发到静态内容
【发布时间】:2016-06-14 14:34:42
【问题描述】:

为了优化缓存,我在图像等的 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"

但是,当我在应用引擎服务器上部署整个内容时,响应具有此缓存标头(并且没有“过期”):

Cache-Control:"private"

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

我怎样才能做到这一点?

更新:

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

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

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

【问题讨论】:

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


    【解决方案1】:

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

    代替:

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

    使用以下架构:

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

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

    【讨论】:

    • 这听起来是个好主意!我会尽快尝试 :) (只是为了更好地理解:它不是当前时间戳,而是我在服务器启动后的第一次请求时设置为最终静态变量的时间戳——最好是编译时或部署时的时间戳,但还不确定如何执行此操作。)
    • 该值也会起作用。我猜你不需要它在请求之间是唯一的,只是在不同版本的应用程序之间
    【解决方案2】:

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

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

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

    【讨论】:

    • 根据我的经验,这不是全部真相。看起来每个资源都作为动态资源和静态资源存在——并且通过应用过滤器,选择了动态资源。我想这以某种方式解释了我的问题:&lt;static-files&gt; 不适用于我过滤的资源
    • 嗯,默认情况下,WAR 中的所有文件都被视为静态文件和资源文件,JSP 文件除外。 (cloud.google.com/appengine/docs/java/config/…)。也就是说,appengine-web.xml 中的静态定义文件将由 Google 直接提供,而不会影响您的应用。也是资源意味着您也可以通过java.io.Filejavax.servlet.ServletContext.getResource/getResourceAsStream 访问它们。没有更多信息,我不确定为什么 &lt;static-file&gt; 指令在生产中没有生效。
    • 在我看来 &lt;static-file&gt; 适用于实际存在的文件,例如foo.png 但如果它们不存在(例如 foo.1456871418309.png),请转到应用引擎(及其过滤器)。那是对的吗?然而,一旦在 App Engine 上,似乎就没有办法回到提供静态文件的机器了……
    • 正确,就是这样。如果文件不存在,请求级联到您的应用程序。确实没有办法重定向到静态服务文件。
    猜你喜欢
    • 2011-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-15
    • 2011-02-25
    • 2011-07-14
    • 2017-12-22
    • 1970-01-01
    相关资源
    最近更新 更多