如何禁用静态资源的缓存,如JSF2中的.css和.js? [英] How to disable caching of static assets like .css and .js in JSF2?

查看:601
本文介绍了如何禁用静态资源的缓存,如JSF2中的.css和.js?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试设置一个项目,以便不缓存静态资源.css和.js。我们似乎对一些人有一些内部缓存问题,我希望它清除它。



我有一个阶段侦听器,基本上稍微修改版本的此 http://turbomanage.wordpress.com/ 2006/08/08 / disable-browser-caching-in-jsf /



我的班级:

  package com.ods.common.jsf.phaselistener; 

import javax.faces.context.FacesContext;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;
import javax.servlet.http.HttpServletResponse;

public class CacheControlPhaseListener implements PhaseListener
{
public PhaseId getPhaseId()
{
return PhaseId.RENDER_RESPONSE;
}

public void afterPhase(PhaseEvent事件)
{
}

public void beforePhase(PhaseEvent事件)
{
FacesContext facesContext = event.getFacesContext();
HttpServletResponse response =(HttpServletResponse)facesContext
.getExternalContext()。getResponse();
response.setHeader(Cache-control,no-cache); // HTTP 1.1
response.setHeader(Cache-control,no-store); // HTTP 1.1
response.setHeader(Cache-control,must-revalidate); // HTTP 1.1
// response.setHeader(Pragma,no-cache); // HTTP 1.0
response.setHeader(Allow,GET); //允许GET方法
response.setHeader(Allow,POST); //仅允许POST方法
response.setDateHeader(Expires,-1); //阻止代理服务器上的缓存

/ *我添加了什么* /
response.setHeader(Pragma,no-cache);
response.setHeader(Content-type,x-javascript);
//下面是我通过Firebug看到的css / js资源的内容类型
response.setHeader(Content-type,application / x-javascript);
response.setHeader(Content-type,text / css);
}
}



我添加到faces-config.xml:

 < lifecycle> 
< phase-listener id =nocache> com.ods.common.jsf.phaselistener.CacheControlPhaseListener< / phase-listener>
< / lifecycle>

我的.xhtml页面过去有过期标题:

  Expires Thu,01 Jan 1970 00:00:00 GMT 

所以这似乎是有点工作...我假设这个日期是从Expires -1(设置到unix时代)。



您可以看到,我已经尝试为某些javascript和CSS设置适当的内容类型标头,但这些资源上的过期日期是未来一周。



任何人有什么想法?此外,我是一个前端开发人员,而不是后端的java家伙。我可以搞砸与Java,但我是defintiely不是一个java开发人员。这是我JSF的第一份工作,因为你可以愚蠢的很好:)

解决方案

code> setHeader()您将覆盖之前设置的任何头。而是使用 addHeader(),或者只是将所有值分隔为标题值。这是完整的集合:

  response.setHeader(Cache-Control,no-cache,no-store, revalidate); // HTTP 1.1。 
response.setHeader(Pragma,no-cache); // HTTP 1.0。
response.setDateHeader(Expires,0); // Proxies。

另一个错误是, PhaseListener isn这是最好的地方。它只在JSF页面请求上调用,而不是在webbrowser独立调用的静态资源请求上调用。换句话说,只有JSF页本身具有缓存禁用,但是所有< script> < link> < img> 等将生成新的请求,不会调用 PhaseListener ,因为那些不是JSF页面



而是使用 过滤器

  @WebFilter(/ *)
public class NoCacheFilter implements过滤{

@Override
public void doFilter(ServletRequest req,ServletResponse res,FilterChain chain)throws IOException,ServletException {
HttpServletResponse response =(HttpServletResponse)res;
response.setHeader(Cache-Control,no-cache,no-store,must-revalidate); // HTTP 1.1。
response.setHeader(Pragma,no-cache); // HTTP 1.0。
response.setDateHeader(Expires,0); // Proxies。
chain.doFilter(req,res);
}

// ...(只保留init()和destroy()NO-OP)
}
pre>

如果你定位一个Servlet 3.0容器(Tomcat 7,Glassfish 3等),然后 web.xml (或 faces-config.xml )注册是不必要的。 @WebFilter(/ *)将自动注册它并将其映射到 / * 的URL模式 > 确保网页





不相关到具体问题,完全禁用静态资源缓存不是最好的主意。它不必要地花费网络带宽。而是寻找不同的解决方案,例如在查询字符串中包含服务器启动时间戳。



Eg

 < script src =foo.js?#{startup.time}>< / script& 

faces-config.xml

 < managed-bean> 
< managed-bean-name> startup< / managed-bean-name>
< managed-bean-class> java.util.Date< / managed-bean-class>
< managed-bean-scope>应用程序< / managed-bean-scope>
< / managed-bean>

此示例将强制浏览器在服务器重新启动时重新加载资源。


I'm trying to set up a project to not cache static assets .css and .js. We seem to be having some internal caching issues for some people and I'm hoping this clears it up.

I have in place a phase listener, basically a slightly modified version of this http://turbomanage.wordpress.com/2006/08/08/disable-browser-caching-in-jsf/

My class:

package com.ods.common.jsf.phaselistener;

import javax.faces.context.FacesContext;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;
import javax.servlet.http.HttpServletResponse;

public class CacheControlPhaseListener implements PhaseListener
{
public PhaseId getPhaseId()
{
    return PhaseId.RENDER_RESPONSE;
}

public void afterPhase(PhaseEvent event)
{
}

public void beforePhase(PhaseEvent event)
{
    FacesContext facesContext = event.getFacesContext();
    HttpServletResponse response = (HttpServletResponse) facesContext
            .getExternalContext().getResponse();
    response.setHeader("Cache-control", "no-cache"); // HTTP 1.1
    response.setHeader("Cache-control", "no-store"); // HTTP 1.1
    response.setHeader("Cache-control", "must-revalidate"); // HTTP 1.1
    // response.setHeader("Pragma","no-cache"); //HTTP 1.0
    response.setHeader("Allow", "GET"); // Allowing GET Method only
    response.setHeader("Allow", "POST");// Allowing POST Method only
    response.setDateHeader("Expires", -1); // prevent caching at the proxy server

            /*what I've added*/
    response.setHeader("Pragma", "no-cache");
    response.setHeader("Content-type", "x-javascript");
            //below are the content types I'm seeing for the css/js assets via Firebug
    response.setHeader("Content-type", "application/x-javascript");
    response.setHeader("Content-type", "text/css");
}
}

My addition to faces-config.xml:

<lifecycle>
    <phase-listener id="nocache">com.ods.common.jsf.phaselistener.CacheControlPhaseListener</phase-listener>
</lifecycle>

My .xhtml page is getting an expires header in the past:

Expires Thu, 01 Jan 1970 00:00:00 GMT

So this seems to be working somewhat...I'm assuming this date is from the Expires -1 (setting it to the unix epoch).

As you can see, I've tried setting appropriate content-type headers for some javascript and css but the expire dates on those assets are a week into the future.

Anyone have any ideas? Also, I'm a front-end developer, not a back-end java guy. I can mess around with Java, but I'm defintiely not a java developer. This is my first job with JSF as well so as much as you can dumb down would be good :)

解决方案

With the setHeader() you're overridding any previously set header. Rather use addHeader() instead, or just put all values commaseparated as the header value. Here's the complete set:

response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
response.setHeader("Pragma", "no-cache"); // HTTP 1.0.
response.setDateHeader("Expires", 0); // Proxies.

Your another mistake is that a PhaseListener isn't the best place for this. It's only invoked on JSF page requests, not on static resource requests which are independently invoked by the webbrowser. In other words, only the JSF page itself has caching disabled, but all <script>, <link>, <img>, etc will generate new requests which doesn't invoke that PhaseListener because those are not JSF pages.

Rather use a Filter.

@WebFilter("/*")
public class NoCacheFilter implements Filter {

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;
        response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
        response.setHeader("Pragma", "no-cache"); // HTTP 1.0.
        response.setDateHeader("Expires", 0); // Proxies.
        chain.doFilter(req, res);
    }

    // ... (just keep init() and destroy() NO-OP)
}

If you target a Servlet 3.0 container (Tomcat 7, Glassfish 3, etc), then web.xml (or faces-config.xml) registration is not necessary. The @WebFilter("/*") will autoregister it and map it on an URL pattern of /* which thus covers all requests.

See also:


Unrelated to the concrete problem, disabling the static asset caching altogether isn't the best idea. It unnecessarily costs network bandwidth. Rather look for a different solution, for example including the server startup timestamp in the query string.

E.g.

<script src="foo.js?#{startup.time}"></script>

with in faces-config.xml

<managed-bean>
    <managed-bean-name>startup</managed-bean-name>
    <managed-bean-class>java.util.Date</managed-bean-class>
    <managed-bean-scope>application</managed-bean-scope>
</managed-bean>

This example would force the browser to reload the assets whenever the server has restarted.

这篇关于如何禁用静态资源的缓存,如JSF2中的.css和.js?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆