How to set Expires HTTP header on a single JS file

2020-02-08 09:43发布

问题:

I have a js file which is cached between 5-10 minutes, depending on whether I'm using tomcat from the eclipse (via GWT plugin) or starting tomcat as standalone.
This is strange as I'm using GWT as my framework and this file should not be cached at all (it's a nocache.js file to those of you who know GWT). I've read on a GWT Google group thread that it's a container configuration issue, and somewhere else that it's something I need to define in the containing HTML file.
Basically, I'm confused right now as I have no clue on how to get this file to not cache. Please note that this js is generated by GWT and I cannot modify it.

Thanks for any help, Ittai

回答1:

Using a javax.servlet.Filter

One way to do this in a portable way (across different app servers), is using Filters. In your web.xml add the following:

  <filter>
    <filter-name>headersFilter</filter-name>
    <filter-class>MyHeadersFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>headersFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

Then implement your MyHeadersFilter like:

public class MyHeadersFilter implements Filter {

  @Override
  public void doFilter(final ServletRequest request,
         final ServletResponse response, final FilterChain chain)
         throws IOException, ServletException {

      final HttpServletRequest httpRequest = (HttpServletRequest) request;
      final String requestUri = httpRequest.getRequestURI();

      final HttpServletResponse httpResponse = (HttpServletResponse) response;


      if (requestUri.contains(".nocache.")) {
        httpResponse.addHeader("Cache-Control", "no-cache");
        ...

      } else if (...) {
        ...
      }

      chain.doFilter(request, response);
  }
}

Optional: Configurable Filters

You can also make your filter configurable from your web.xml, by using <init-param>s:

  <filter>
    <filter-name>headersFilter</filter-name>
    <filter-class>MyHeadersFilter</filter-class>
    <init-param>
        <param-name>myParam</param-name>
        <param-value>myValue</param-value>
    </init-param>
  </filter>

Add the following to MyHeadersFilter:

    private FilterConfig filterConfig;

    @Override
    public void init(final FilterConfig filterConfig) throws ServletException {
        this.filterConfig = filterConfig;
    }

    @Override
    public void destroy() {
        this.filterConfig = null;
    }

That makes it possible to access your init-param(s) using:

filterConfig.getInitParameter("myParam")


回答2:

There is a Filter available in tomcat 7

<filter>
<filter-name>ExpiresFilter</filter-name>
<filter-class>org.apache.catalina.filters.ExpiresFilter</filter-class>
<init-param>
<param-name>ExpiresByType image</param-name>
<param-value>access plus 10 days</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>ExpiresFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>

You can find more details here

https://tomcat.apache.org/tomcat-7.0-doc/api/org/apache/catalina/filters/ExpiresFilter.html