5

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

PHPでこれを実現する方法は、CVSタグから読み取ることです。出力するHTMLを作成するときは、CVSタグを読み取り、それを使用してjavascriptパスの最後に追加して、次のようなスクリプトタグを作成します。

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

アプリが変更されていない限り、タグは同じままであるため、クエリ文字列も変更されます。有効期限がはるかに長いため、ブラウザはJSをキャッシュし、ネットワークリクエストをまったく実行しないようにする必要があります。アプリが更新されるたびに、そのクエリ文字列が変更され、ブラウザはそれをダウンロードする必要があります。

これはIE8でうまく機能します。私の問題はFirefoxにあります。Firefoxはファイルをキャッシュしますが、次にページをロードすると、Firebugは304応答を表示します。これは、ファイルに対してネットワークリクエストを実行し、ファイルが変更されていないことを示しています。

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

関連:Firefoxは何をキャッシュしないことにしましたか? どうやら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の[キャッシュ]タブには次のように書かれています。

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
4

4 に答える 4

6

Firefoxがキャッシュされた応答を指定して条件付きGETを作成するかどうかを決定するために使用するロジックは、次のようになります。

  1. 関連するVaryヘッダーがある場合は、再検証します。
  2. このリクエストがキャッシュから強制的にロードされることになっている場合は、再検証しないでください。
  3. このリクエストに「常に検証」フラグがある場合は、再検証します。
  4. この要求に「検証しない」フラグがある場合は、これがストアなしの応答またはSSLのキャッシュなしの応答である場合にのみ再検証してください。
  5. 応答状況コードがキャッシュ可能でない場合、応答がキャッシュなしまたはストアなしの場合、または有効期限が応答の日付より前である場合は、再検証してください。
  6. クエリパラメータがあり、応答に明示的なExpiresまたはmax-ageがない場合は、再検証します。
  7. 応答の有効期限が過ぎている場合は、再検証します(「セッションごとに1回だけユーザー設定を再検証する」が設定されている場合を除く)。

したがって、あなたの場合、200応答に実際に有効期限または最大年齢情報を設定していると仮定すると、条件付きGETはありません。

とはいえ、FirefoxのHTTP情報をトレースしようとするツールの中には、実際には再検証の動作に影響を与えるものがあるため、それに遭遇する可能性があります。

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

于 2011-10-03T19:47:44.817 に答える
0

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

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

Firefoxが行うリクエストは、ほんの数バイトの大きさです(ファイルサイズ、日付など)。そのため、名前に関係なく、Firefoxはそれをキャッシュします(無効にされていない場合)。ファイル自体が変更された場合、Firefoxはファイルを再ダウンロードすることを決定します。

あなたが指摘しているのは、実際には正しい振る舞いです。

于 2011-10-03T19:30:09.637 に答える
0

ファイルがリロードされることを絶対に確認したい場合は、バージョン番号/キャッシュバスター文字列をファイル名に直接入力することをお勧めします。shipments_v2.jsしたがって、またはのようなものがありますshipments_(unix_timestamp).js。これにより、プロキシやその他の種類のキャッシュメカニズムが処理されます。

于 2011-10-03T19:53:10.383 に答える
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;
        }
  [..]
  }
于 2015-09-24T16:57:01.207 に答える