2011-10-03 6 views
5

私がしたいのは、アプリケーションの新しいバージョンが更新されるたびにjavascriptがダウンロードされるように、javascriptパスの最後にクエリ文字列を追加することです。ただし、クエリ文字列が同じであれば、http要求を行わずにキャッシュされたバージョンを使用して、スクリプトが変更されたかどうかを確認する必要があります。Firefoxはjavascriptをキャッシュし、パスにクエリー文字列がある場合はリクエストなしで使用しますか?

PHPでこれを達成する方法は、CVSタグから読み取ることです。アプリ限り

<script src="javascript/messages/shipments.js?TPRSAPPS-DEV2_090828145712237-BRANCH" type="text/javascript"></script> 

を:私は出力するHTMLを構築していた場合、それはこのようになりますスクリプトタグを作成するように、私はCVSタグを読み、JavaScriptのパスの最後に追加することを使用します変更されていない場合、タグは同じままであり、したがってクエリ文字列も変更されません。ブラウザーはJSをキャッシュし、満了日が近いためにネットワーク要求をまったく実行しません。アプリケーションが更新されるたびに、そのクエリ文字列が変更され、ブラウザはそれをダウンロードする必要があります。

これはIE8でうまくいきます。私の問題はFirefoxにあります。 Firefoxはファイルをキャッシュしますが、次回にページをロードするときに、Firebugは304応答を表示します。これは、ファイルに対するネットワーク要求がまだ行われていないことを示しています。

私の質問は、firefoxはクエリ文字列があるときにexpiresヘッダとjavascriptのキャッシュを無視しますか?

関連:what does firefox decide not to cache? 明らかにRailsは何か類似しています。しかし、これは私の質問に答えるものではありません。ここで

が、私は、このファイルに戻って取得しています応答である:

https://appdev.prsx.net/~jhargett/PRSApps-Motorlog/javascript/menuReader.js?TPRSAPPS-DEV2_090828145712237-BRANCH-DIFFERENT 

HTTP/1.1 304 Not Modified 
Date: Mon, 03 Oct 2011 18:35:26 GMT 
Server: Apache/2.2.3 (Red Hat) 
Connection: close 
Etag: "179010-3f8-49a9a74334200" 
Vary: Accept-Encoding 

Firebugの中Cacheタブは言う:あなたが見ているのは何

Last Modified Mon Oct 03 2011 13:35:26 GMT-0500 (Central Daylight Time) 
Last Fetched Mon Oct 03 2011 13:35:26 GMT-0500 (Central Daylight Time) 
Expires Fri Oct 28 2011 18:33:31 GMT-0500 (Central Daylight Time) 
Data Size 345 
Fetch Count 12 
Device disk 
+3

あなたのHTTPレスポンスヘッダーは次のようになりますか?それはここで重要なことです。 – Pointy

+2

304を実行するのは正常です。 Firefoxは少なくとも "if-modified-since"ヘッダーを使ってページ上のすべてのリソースに対してGETリクエストを送信します。新しいコンテンツ(200)または変更されていない304で返信するのはサーバーに任されます。 –

+0

期限切れヘッダが遠い場合は、まったくリクエストを行う必要があります。 –

答えて

6

Firefoxはキャッシュされたレスポンス与えられた条件付きのGETを行うかどうかを決定するために使用するロジックはそうのようなものです:

  1. 関連が再検証、Varyヘッダがある場合。
  2. この要求がキャッシュから強制ロードされることになっている場合は、再検証しないでください。
  3. この要求に「always validate」フラグがある場合は、再検証します。
  4. このリクエストに「never validate」フラグが設定されている場合は、これがストアレスレスポンスまたはSSLノー・キャッシュ・レスポンスである場合にのみ再検証します。
  5. 応答ステータスコードがキャッシュ不可能であるか、応答がno-cacheまたは no-storeである場合、または有効期限が応答日より前である場合は、再検証します。
  6. クエリパラメータがあり、応答に明示的な有効期限または最大有効期間がない場合は、再検証します。
  7. レスポンスの有効期限が過去のものである場合は、「セッションごとに1回のみユーザーの再設定を有効にする」以外は再検証してください。

200件の応答で実際に有効期限や最大年齢情報が設定されていると仮定すると、条件付きGETはありません。

FirefoxのHTTP情報をトレースしようとするツールの中には、実際には再検証の動作に影響を与えるものがあると言われています。

https://developer.mozilla.org/en/HTTP_Loggingの手順に従ってログを作成することをお勧めします。これは、条件付きGETが行われている理由を正確に伝えます。ログの正しい部分が見つかった場合は(「nsHttpChannel :: CheckCache enter」を検索してください。上記のロジックを実装する関数からのロギング)。

+0

私はこの答えと上記のPointyのコメントに基づいて私の答えを見つけました。元のキャッシュされていない(200)負荷の応答ヘッダーを再調査しました。明示的な期限切れヘッダーはありませんでした。 Firefoxの[キャッシュ]タブに有効期限が表示されていたにもかかわらず、HTTPヘッダーからその日付を取得できませんでした。 –

+1

@ Jon HTTP RFCは、現在の時刻とDateヘッダーに基づいて有効期限を決定するヒューリスティックを定義します。だから、上記の項目6を実行していました。これはhttp://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.9パラグラフ2を実装しているだけです。 –

0

は、実際にファイルをダウンロードするよりも別の何かでありますそれが変更されていないと言う。

Firefoxは、ファイル自体ではなく、ファイル情報を取得するためにHTTPリクエストを行います。これは実際には、IEがやっているこのスマートなことをやっていることを意味します。

リクエストのファイアフォックスは、わずか2バイトの大きさ(ファイルサイズ、日付など)です。だから、名前に関係なく、firefoxはそれをキャッシュします(無効にしない限り)。ファイル自体が変更された場合、firefoxはファイルを再ダウンロードすることを決定します。

あなたが指摘していることは、実際には正しい動作です。

+0

ファイル全体をダウンロードするのではなく、更新されているかどうかを確認するだけです。しかし、far-future expires([yahoo](http://developer.yahoo.com/performance/rules.html))の追加のポイントは、これをチェックするネットワーク要求さえ回避することです。実際、Firefoxはクエリ文字列がないときにリクエストを行いません。それはキャッシュから引っ張り出し、Firebugは200レスポンスのグレーアウトされた行を表示し、要求なしでキャッシュからファイルを使用したことを示します。 –

0

ファイルが再ロードされることを確実にしたい場合は、バージョン番号/キャッシュバスター文字列を直接ファイル名に入れてください。だから、shipments_v2.jsshipments_(unix_timestamp).jsのようなものがあります。これは、プロキシと他の種類のキャッシングメカニズムを処理します。

+0

実際のファイルの名前を変更します。 _v2.jsを取り除いて正しいファイルにリダイレクトするために、htaccessファイルで何かを行うこともできると思います。 –

+0

両方とも有効な発言です。それがもっと大きなプロジェクトなら、おそらくコンテンツを最小限に抑えるためのビルドスクリプトを用意しています。それ以外の場合は手で行うことができます:) – deviousdodo

0

Borisの答えで説明したように、条件付き要求をトリガする条件の1つは、Varyヘッダーの存在です。 Accept-Encodingのバリエーションを削除したくないのですが、URLのバージョン管理をしているときにできることと何ができるのかは、ブラウザには何も再検証しないことです。あなたのケースでは、それはEtagヘッダーです。 Last-Modifiedヘッダーも可能です。あなたはこのように見えるかもしれためにそれを行うためのニスのための 例コード:

sub vcl_recv { 
    [..] 
     if (req.url ~ "\?v=\w+$") { 
      set req.http.X-Versioned = "1"; 
     } 
    [..] 
    } 

    sub vcl_deliver { 
    [..] 
     if (req.http.X-Versioned) { 
      unset resp.http.Etag; 
     } 
    [..] 
    } 
関連する問題