web-dev-qa-db-ja.com

JavaScriptファイルのブラウザーキャッシングを防ぐより良い方法

これが、ブラウザによるJSおよびCSSファイルのキャッシュを防ぐ方法です。これは少しハッキリのようです..より良い方法はありますか?

<%
//JSP code
long ts = (new Date()).getTime(); //Used to prevent JS/CSS caching
%>

<link rel="stylesheet" type="text/css" media="screen" href="/css/management.css?<%=ts %>" />
<script type="text/javascript" src="/js/pm.init.js?<%=ts %>"></script> 
<script type="text/javascript" src="/js/pm.util.func.js?<%=ts %>"></script> 

更新:キャッシュを防止したいのは、新しいリリースを実行するときに、ファイルの新しいバージョンがロードされるようにするためです。

22
Marcus Leon

CSSとJSをキャッシュしたい。彼らが戻ってきたとき、それはウェブページのロードをスピードアップします。タイムスタンプを追加すると、ユーザーは何度もそれをダウンロードする必要があります。

彼らが常に新しいバージョンを持っていることを確認したい場合は、ビルドシステムにタイムスタンプの代わりにファイルの最後にビルド番号を追加させます。

Devだけで問題が発生する場合は、ファイルをキャッシュしないようにブラウザーを設定するか、devページのヘッダーをキャッシュしないように設定してください。

22
epascarello

キャッシングはあなたの友達です。ブラウザーがこれらのファイルを誤ってキャッシュしている場合は、WebサーバーがJSおよびCSSファイル自体(それらを使用するHTMLページではない)とともに送信しているHTTPヘッダーに問題があることを意味します。ブラウザはそれらのヘッダーを使用して、ファイルをキャッシュできるかどうかを判断します。

Webサーバーはこれらのヘッダーを(提供するすべてのJSおよびCSSファイルで)送信して、ブラウザーにそれらをキャッシュしないように指示できます。

Cache-Control: no-cache
Pragma: no-cache
Expires: Sat, 01 Jan 2000 00:00:00 GMT

ただし、サイトのネットワーク負荷が増加し、ユーザーにはページの負荷が遅くなります。もう少し寛大にして、ブラウザがCSSファイルを60秒間キャッシュできるようにすることができます。

Cache-Control: max-age=60

本当に1つのページが読み込まれるたびにブラウザで新しいファイルを確認する場合は、まだ ETagを使用してネットワークトラフィックを節約できます。

Cache-Control: max-age=0
Pragma: no-cache
Expires: Sat, 01 Jan 2000 00:00:00 GMT
ETag: "o2389r-98ur0-w3894tu-q894"

ETagは、ファイルが変更されるたびにWebサーバーが作成する一意の識別子です。次にブラウザーがファイルを必要とするときに、サーバーに「/js/pm.init.jsにはまだETag o2389r98ur0w3894tuq894が残っていますか?」と尋ねられます。その場合、サーバーは単に「はい」と言います。これにより、サーバーはファイル全体を再度送信する必要がなくなり、ユーザーはファイルが読み込まれるのを待つ必要がなくなります。 Win-Win。

ETagを自動生成するようにWebサーバーを説得する方法は、サーバーによって異なります。通常は難しくありません。

あなたが使っているハックを見たことがあります。 Webと同じように、これはかなり効率的ではありませんが、機能します。

19
Jason Orendorff

キャッシュを防止する理由は、新しいリリースを実行するときにファイルの新しいバージョンが確実にロードされるようにするためです。、ここにIS新しいリリース、常にではありません。

そのためには、「ts」の値を時刻ではなくファイルにリンクする必要があります。次のいずれかのシステムを使用できます。

  1. ts =ファイルのタイムスタンプ
  2. ts = FILEのMD5(または任意のチェックサム)
  3. ts =コードのバージョン。展開を行うスクリプトがある場合は、tsに割り当てられるインクルードファイルにバージョンコード(またはリリースの日付)が追加されていることを確認してください。

このようにして、ブラウザは、常に新しいファイルではなく、新しい場合にのみファイルをリロードします。

13
Chris Cinelli

これに対する簡単なアプローチは、タイムスタンプの代わりにURL内のjsまたはcssファイルの最終更新日を使用することです。これにより、サーバー上に新しいバージョンのファイルが存在する場合にのみ、キャッシュが防止されます。

3
user2784850

編集

Spring Bootを使用している場合、変更されたファイルのキャッシュを防止する方がはるかに簡単になりました。

これをapplication.propertiesに追加するだけです。

spring.resources.chain.strategy.content.enabled=true
spring.resources.chain.strategy.content.paths=/**

ThymeleafまたはFreeMarkerを使用している場合は、完全に自動構成されます。 JSPを使用している場合は、ResourceUrlEncodingFilterを手動で宣言する必要があります。

詳細はこちら: http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-developing-web-applications.html#boot-features-spring-mvc-静的コンテンツ

次に続くのは、私の「古い」投稿です。これも機能しますが、さらに作業が必要です。


Javaを使用しているため、プロジェクトの管理にMavenも使用している可能性があります。

その場合、パフォーマンスを改善し、ソフトウェアの新しいリリースが生成されたときにブラウザーが静的リソースをキャッシュしないようにするには、すべてのスタイルシートとJavaScriptファイルをそれらのタイプの単一のファイルに結合する必要があります。新しいリリースを作成するときにリソースURLを変更します。

幸いなことに、mavenはビルド時にこれをすべて実行できます。あなたは必要になるでしょう minify-maven-pluginおよびmaven-replacer-plugin

Pom.xmlのこの抜粋は、あなたが始めるのに役立ちます:

<properties>
    <timestamp>${maven.build.timestamp}</timestamp>
    <maven.build.timestamp.format>yyyyMMddHHmm</maven.build.timestamp.format>
</properties>

<plugin>
    <groupId>com.samaxes.maven</groupId>
    <artifactId>minify-maven-plugin</artifactId>
    <version>1.6</version>
    <executions>
        <execution>
            <id>minify-css</id>
            <phase>process-resources</phase>
            <goals>
                <goal>minify</goal>
            </goals>
            <configuration>
                <linebreak>-1</linebreak>
                <cssSourceDir>resources/css</cssSourceDir>
                <cssSourceFiles>
                    <cssSourceFile>bootstrap.css</cssSourceFile>
                    <cssSourceFile>style.css</cssSourceFile>
                </cssSourceFiles>
                <cssTargetDir>resources/css</cssTargetDir>
                <cssFinalFile>${timestamp}.css</cssFinalFile>
            </configuration>
        </execution>
        <execution>
            <id>minify-js</id>
            <phase>process-resources</phase>
            <goals>
                <goal>minify</goal>
            </goals>
            <configuration>
                <linebreak>-1</linebreak>
                <jsSourceDir>resources/js</jsSourceDir>
                <jsSourceFiles>
                    <jsSourceFile>jquery.js</jsSourceFile>
                    <jsSourceFile>bootstrap.js</jsSourceFile>
                    <jsSourceFile>script.js</jsSourceFile>
                </jsSourceFiles>
                <jsTargetDir>resources/js</jsTargetDir>
                <jsFinalFile>${timestamp}.js</jsFinalFile>
            </configuration>
        </execution>
    </executions>
</plugin>

<plugin>
    <groupId>com.google.code.maven-replacer-plugin</groupId>
    <artifactId>replacer</artifactId>
    <version>1.5.2</version>
    <executions>
        <execution>
            <id>replaceDynPartInResourcePath</id>
            <phase>prepare-package</phase>
            <goals>
                <goal>replace</goal>
            </goals>
            <configuration>
                <ignoreMissingFile>false</ignoreMissingFile>
                <basedir>${project.build.directory}</basedir>
                <file>${project.artifactId}/WEB-INF/views/header.jsp</file>
                <regex>false</regex>
                <replacements>
                    <replacement>
                        <token>$dynamicResourceNamePart$</token>
                        <value>${timestamp}</value>
                    </replacement>
                </replacements>
            </configuration>
        </execution>
    </executions>
</plugin>

これは、header.jspに静的リソースを含める方法です

<c:choose>
    <c:when test="${not fn:contains(pageContext.request.serverName, 'localhost') and empty param.nocombine}">
        <link href="${pageContext.request.contextPath}/resources/css/$dynamicResourceNamePart$.min.css" rel="stylesheet" type="text/css" />
        <script src="${pageContext.request.contextPath}/resources/js/$dynamicResourceNamePart$.min.js" type="text/javascript"></script>
    </c:when>
    <c:otherwise>
        <link href="${pageContext.request.contextPath}/resources/css/bootstrap.css" rel="stylesheet">
        <link href="${pageContext.request.contextPath}/resources/css/style.css" rel="stylesheet">
        <script type="text/javascript" src="${pageContext.request.contextPath}/resources/js/jquery.js"></script>
        <script type="text/javascript" src="${pageContext.request.contextPath}/resources/js/bootstrap.js"></script>
        <script type="text/javascript" src="${pageContext.request.contextPath}/resources/js/script.js"></script>
    </c:otherwise>
</c:choose>
3
yglodt

デバッグの目的で、FireFox用に Web開発者ツールバー をインストールし、そこで「キャッシュを非アクティブ化」してアクティブ化します。

更新:
FireBugをインストールすると、 ネットワークタブの設定でキャッシュも無効にする ができます。

1
powtac

Javaサーブレットフィルターをアプリケーションに含めることができる場合、これが実際の解決策です: CorrectBrowserCacheHandlerFilter.Java

基本的に、ブラウザーが静的ファイルを要求すると、サーバーはすべての要求を同じ要求にリダイレクトしますが、ターゲットの静的ファイルのコンテンツに依存するハッシュクエリパラメーター(たとえば、_?v=azErT_)を使用します。

これを行うと、ブラウザは_index.html_で宣言された静的ファイルをキャッシュすることは決してありません(常に_302 Moved Temporarily_を受け取るため)、ハッシュバージョンのファイルのみをキャッシュします(サーバーは_200_それらのために)。そのため、ブラウザのキャッシュは、ハッシュバージョンの静的ファイルに対して効率的に使用されます。

免責事項:私は_CorrectBrowserCacheHandlerFilter.Java_の作成者です。

0
Anthony O.