web-dev-qa-db-ja.com

Microsoft XmlHttpRequestにキャッシュ制御ディレクティブを尊重させる方法

mSXMLの XmlHttpRequest オブジェクトを使用してリクエストを発行しています:

_IXMLHttpRequest http = new XmlHttpRequest();
http.open("GET", "http://www.bankofcanada.ca/stat/fx-xml.xml", False, "", "");
http.send();
_

そして、sendは成功し、xmlデータを取得します。

ただし、XmlHttpRequestは実際にはネットワークに接続していません(実際のHTTPリクエストは発行されていないことがわかります)。そして、プロセスモニターは、ファイルが実際に私のキャッシュから提供されていることを示しています。

enter image description here

そのため、XmlHttpRequestユーザーエージェントに、キャッシュされたコンテンツが0秒より古いと古すぎることを指示したいと思います。これを行う 標準的な方法 は、要求ヘッダーを追加することです。

_Cache-Control: max-age=0
_

送信リクエストに:

_http = new XmlHttpRequest();
http.open("GET", "http://www.bankofcanada.ca/stat/fx-xml.xml", False, "", "");
http.setRequestHeader("Cache-Control", "max-age=0");
http.send();
_

そして、sendは成功し、xmlデータを取得します。

ただし、XmlHttpRequestは実際にはネットワークに接続していません(実際のHTTPリクエストは発行されていないことがわかります)。プロセスモニターには、ファイルが実際にキャッシュから提供されていることが表示されます。

何が問題なのでしょうか? _max-age_は私が思っていることをしていませんか?

From RFC 2616-Hypertext Transfer Protocol、Part 14:Header Field Definitions

その他のディレクティブを使用すると、ユーザーエージェントは基本的な有効期限メカニズムを変更できます。これらのディレクティブはリクエストで指定してもよいです:

最大年齢
クライアントが、指定された時間(秒)以下の応答をクライアントが受け入れる用意があることを示します。 max-staleディレクティブも含まれていない限り、クライアントは古い応答を受け入れる用意がありません。

まさに私が欲しいもの。

_Cache-Control: max-age=0_が私が望んでいるものと正確に一致していませんか、またはMSXMLのXmlHttpRequestオブジェクトにバグがありますか?

1つを更新

これはMSXML XmlHttpRequest COMオブジェクトです。

  • CLSID:{88d96a0a-f192-11d4-a65f-0040963251e5}
  • ProgID:Msxml2.XMLHTTP.6.0

2つ更新

_max-age_ディレクティブは、すべてのキャッシュを遵守するためにクライアントによって追加されます。 RFCから:

Cache-Control general-headerフィールドは、要求/応答チェーンに沿ったすべてのキャッシュメカニズムに従う必要があるディレクティブを指定するために使用されます。ディレクティブは、キャッシュが要求または応答に悪影響を与えることを防ぐための動作を指定します。これらのディレクティブは通常、デフォルトのキャッシュアルゴリズムをオーバーライドします。リクエストにディレクティブが存在しても、応答で同じディレクティブが指定されることを意味しないという点で、キャッシュディレクティブは単方向です。

Max-ageはサーバー用ではありません。サーバーにとっては意味がありません。これは、ユーザーとサーバー間のすべてのキャッシングシステムの間を対象としています。

更新3

From W3C XmlHttpRequest

ユーザーエージェントがHTTPキャッシュを実装する場合shouldsetRequestHeader() によって設定された_Cache-Control_リクエストヘッダーを尊重します(例:_Cache-Control: no-cache_キャッシュをバイパスします)。 必須ではないエンドユーザーが明示的にそのような動作を要求しない限り(たとえば、ページを再読み込みすることによって)、_Cache-Control_またはPragma要求ヘッダーを自動的に送信します。

exampleに続いて、_no-cache_ディレクティブを使用してみました:

_http = new XmlHttpRequest();
http.open("GET", "http://www.bankofcanada.ca/stat/fx-xml.xml", False, "", "");
http.setRequestHeader("Cache-Control", "no-cache");
http.send();
_

また、XmlHttpRequestクライアントは、サーバーにまったく照会せずに、キャッシュから完全に要求を処理します。

W3Cは、キャッシュがある場合、setRequestHeaderを介して設定されている場合、_Cache-Control_を尊重する必要があると述べています。 MicrosoftのXmlHttpRequestはその要件を順守していないようです。

30
Ian Boyd

残念ながら、XMLHttpRequestオブジェクトはWinInetに基づいているため、この方法で設計されました。また、サーバー側からの使用はお勧めしません。同じ機能を持つ ServerXMLHttpRequest を使用する必要がありますが、代わりに WinHTTP を使用します。詳細は [〜#〜] faq [〜#〜] を参照してください。 ServerXMLHttpドキュメントの説明には、次のように記載されています。

HTTPクライアントスタックは、より長い稼働時間を提供します。 URLキャッシング、プロキシサーバーの自動検出、HTTP/1.1チャンキング、オフラインサポート、GopherおよびFTPプロトコルのサポートなど、サーバーアプリケーションにとって重要ではないWinInet機能は、新しいHTTPサブセットに含まれていません。

つまり、 XmlHttpRequest を使用するのではなく、

IXMLHTTPRequest http = CreateComObject("Msxml2.XMLHTTP.6.0");     http.open("GET", "http://www.bankofcanada.ca/stat/fx-xml.xml", False, "", "");
http.setRequestHeader("Cache-Control", "max-age=0");
http.send();

ServerXmlHttpRequest を使用できます。

IXMLHTTPRequest http = CreateComObject("Msxml2.ServerXMLHTTP");
http.open("GET", "http://www.bankofcanada.ca/stat/fx-xml.xml", False, "", "");
http.setRequestHeader("Cache-Control", "max-age=0");
http.send();

または WinHttpRequest

IWinHttpRequest http = CreateComObject("WinHttp.WinHttpRequest.5.1");
http.open("GET", "http://www.bankofcanada.ca/stat/fx-xml.xml", False, "", "");
http.setRequestHeader("Cache-Control", "max-age=0");
http.send();
17
Garett

If-None-Matchヘッダー、最後のリクエストのETagと一致しない値を指定すると機能します。

例えば:

req.open("GET", url, false);
req.setRequestHeader("If-None-Match", "\"doesnt-match-anything\"");
req.send();

これには、応答にETagを含める必要がある場合とない場合があります。 (私は、各応答にETag値を含むサービスでのみ試しました。)

5
J. Mullaney

リクエストごとに変化する偽のパラメーターをURIの末尾に追加できますか?

http.open("GET", "http://www.bankofcanada.ca/stat/fx-xml.xml?requestID=42", False, "", "");
1
blue t-shirt

標準のWindowsクライアントでの迅速で汚れた回避策は
-インターネットオプション
-全般
-閲覧履歴の設定
-保存されているページの新しいバージョンを確認します。
tickle「(x)毎回Webページにアクセスする」
これでMsxml2.XMLHTTP.x.0オブジェクトはキャッシュを使用しなくなりました...

1
anonymous

私はこれをキープアライブセッションに使用します。
コツは、「If-Modified-Since」というヘッダーを、ブラウザーがキャッシュした値よりも新しい値で使用することです。

g_AjaxObj.onreadystatechange = function() { if(g_AjaxObj.readyState === 4) { AjaxOnComplete_("KeepAlive"); }};
g_AjaxObj.open('GET', URL, true);
g_AjaxObj.setRequestHeader("If-Modified-Since", new Date().toUTCString());
g_AjaxObj.send(null);
1
tranzitwww

古いmsxmlライブラリの場合、uriアドレスにはランダムに生成された値を使用します。例:

http:// youlink?mysession = random_number

wojtek

0
wojtek

このヘッダーはサーバー用であり、ブラウザーはイベントを要求しないので、役に立ちません。

簡単なトリックは次のようにページをロードすることです:

http.open("GET", "http://www.bankofcanada.ca/stat/fx-xml.xml?"+Math.random(), False, "", "");
0
jujule

これは私を夢中にさせていました。これはSOスレッドが回答を提供するのに最も近づきました。残念ながら、テスト中に実際に機能するスレッドはありませんでした。正しく機能することをテストした唯一の解決策は、次の設定でした。

ヘッダープラグマ:キャッシュなし

IE頭痛の種で他の人を救うことを願っています。

ところで、これはStackOverflowスレッドで、プラグマとキャッシュコントロールの違いを明らかにするのに最適です。 プラグマヘッダーとキャッシュコントロールヘッダーの違い?

0
MarkCheshire

'cache-control:private'をヘッダーとして送信してみてください。これは私のために働きました:

var request = new XMLHttpRequest();
request.open("GET", 'http://myurl.com' , false); 

request.setRequestHeader("cache-control", "private");

No-cacheとmax-ageの両方が無視されるWindows 8用のHTML&Javascriptアプリを書いています。私にとって、上記はうまく機能します。

私はヘッダーに慣れていなかったので、キャッシュ制御を少し掘り下げました:プライベート...

Indicates that all or part of the response message is intended for a single user and MUST NOT be cached by a shared cache, such as a proxy server.

Cache-Controlとは:private? および http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html から

したがって、基本的に、これはキャッシュエントリを作成することはなく、したがって、「キャッシュバスター」乱数パラメーターの場合と同様に、不要であることがわかっているキャッシュエントリは追加されません。

0
Matt

その欠点は、同じコンテンツの複数のコピーでキャッシュをフラッディングすることです。バグの多いhttpエージェントをハックするかもしれませんが、実際の解決策は、それらに対してではなく、キャッシュメカニズムを使用することです。 –

これは理想的ではなく、実際の解決策でもないことに同意しますが、Mozillaは実際にこれを回避策として推奨しているので、ひどすぎてはなりません- https://developer.mozilla。 org/en-US/docs/DOM/XMLHttpRequest/Using_XMLHttpRequest

その上、私はこれを解決しようとして私の髪を引き裂いていました。私は、ユーザーがブラウザをクリアすることをユーザーに頼らなければなりませんでした(ユーザーは、忘れてしまいます)。これは私にとって天の恵みです!

0
Sue Smiles