4

静的アセット.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 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");
}
}

私のfaces-config.xmlへの追加:

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

私の.xhtmlページは過去にexpiresヘッダーを取得しています:

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

したがって、これはある程度機能しているようです...この日付はExpires -1からのものであると想定しています(UNIXエポックに設定)。

ご覧のとおり、一部のjavascriptとcssに適切なコンテンツタイプヘッダーを設定しようとしましたが、これらのアセットの有効期限は1週間先です。

誰かアイデアはありますか?また、私はフロントエンドの開発者であり、バックエンドのJavaの人ではありません。私はJavaをいじることができますが、私は間違いなくJava開発者ではありません。これはJSFでの私の最初の仕事でもあるので、あなたが呆然とすることができる限り良いでしょう:)

4

1 に答える 1

13

を使用するsetHeader()と、以前に設定したヘッダーをオーバーライドしています。代わりに使用addHeader()するか、すべての値をカンマ区切りでヘッダー値として配置します。完全なセットは次のとおりです。

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.

あなたの別の間違いは、PhaseListenerこれに最適な場所ではないということです。これは、Web ブラウザによって個別に呼び出される静的リソース リクエストではなく、JSF ページ リクエストでのみ呼び出されます。つまり、JSF ページ自体のみがキャッシュを無効にしますが、すべて<script>の 、<link><img>などは、JSF ページではないため、それを呼び出さない新しいリクエストを生成しPhaseListenerます。

むしろ使用して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)
}

Servlet 3.0 コンテナー (Tomcat 7、Glassfish 3 など) を対象とする場合、web.xml(またはfaces-config.xml) 登録は必要ありません。はそれ@WebFilter("/*")を自動登録し、すべてのリクエスト/*をカバーする URL パターンにマップします。

以下も参照してください。


具体的な問題とは関係ありませんが、静的アセットのキャッシュを完全に無効にすることは最善の方法ではありません。ネットワーク帯域幅を不必要に消費します。代わりに、クエリ文字列にサーバーの起動タイムスタンプを含めるなど、別の解決策を探してください。

例えば

<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>application</managed-bean-scope>
</managed-bean>

この例では、サーバーが再起動するたびにブラウザにアセットを再読み込みさせます。

于 2012-06-01T17:11:03.560 に答える