mSXMLの XmlHttpRequest オブジェクトを使用してリクエストを発行しています:
_IXMLHttpRequest http = new XmlHttpRequest();
http.open("GET", "http://www.bankofcanada.ca/stat/fx-xml.xml", False, "", "");
http.send();
_
そして、send
は成功し、xmlデータを取得します。
ただし、XmlHttpRequest
は実際にはネットワークに接続していません(実際のHTTPリクエストは発行されていないことがわかります)。そして、プロセスモニターは、ファイルが実際に私のキャッシュから提供されていることを示しています。
そのため、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
オブジェクトにバグがありますか?
これはMSXML XmlHttpRequest
COMオブジェクトです。
_max-age
_ディレクティブは、すべてのキャッシュを遵守するためにクライアントによって追加されます。 RFCから:
Cache-Control general-headerフィールドは、要求/応答チェーンに沿ったすべてのキャッシュメカニズムに従う必要があるディレクティブを指定するために使用されます。ディレクティブは、キャッシュが要求または応答に悪影響を与えることを防ぐための動作を指定します。これらのディレクティブは通常、デフォルトのキャッシュアルゴリズムをオーバーライドします。リクエストにディレクティブが存在しても、応答で同じディレクティブが指定されることを意味しないという点で、キャッシュディレクティブは単方向です。
Max-ageはサーバー用ではありません。サーバーにとっては意味がありません。これは、ユーザーとサーバー間のすべてのキャッシングシステムの間を対象としています。
From W3C XmlHttpRequest :
ユーザーエージェントがHTTPキャッシュを実装する場合should
setRequestHeader()
によって設定された_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はその要件を順守していないようです。
残念ながら、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();
If-None-Match
ヘッダー、最後のリクエストのETag
と一致しない値を指定すると機能します。
例えば:
req.open("GET", url, false);
req.setRequestHeader("If-None-Match", "\"doesnt-match-anything\"");
req.send();
これには、応答にETag
を含める必要がある場合とない場合があります。 (私は、各応答にETag
値を含むサービスでのみ試しました。)
リクエストごとに変化する偽のパラメーターをURIの末尾に追加できますか?
http.open("GET", "http://www.bankofcanada.ca/stat/fx-xml.xml?requestID=42", False, "", "");
標準のWindowsクライアントでの迅速で汚れた回避策は
-インターネットオプション
-全般
-閲覧履歴の設定
-保存されているページの新しいバージョンを確認します。
tickle「(x)毎回Webページにアクセスする」
これでMsxml2.XMLHTTP.x.0オブジェクトはキャッシュを使用しなくなりました...
私はこれをキープアライブセッションに使用します。
コツは、「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);
このヘッダーはサーバー用であり、ブラウザーはイベントを要求しないので、役に立ちません。
簡単なトリックは次のようにページをロードすることです:
http.open("GET", "http://www.bankofcanada.ca/stat/fx-xml.xml?"+Math.random(), False, "", "");
これは私を夢中にさせていました。これはSOスレッドが回答を提供するのに最も近づきました。残念ながら、テスト中に実際に機能するスレッドはありませんでした。正しく機能することをテストした唯一の解決策は、次の設定でした。
ヘッダープラグマ:キャッシュなし
IE頭痛の種で他の人を救うことを願っています。
ところで、これはStackOverflowスレッドで、プラグマとキャッシュコントロールの違いを明らかにするのに最適です。 プラグマヘッダーとキャッシュコントロールヘッダーの違い?
'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 から
したがって、基本的に、これはキャッシュエントリを作成することはなく、したがって、「キャッシュバスター」乱数パラメーターの場合と同様に、不要であることがわかっているキャッシュエントリは追加されません。
その欠点は、同じコンテンツの複数のコピーでキャッシュをフラッディングすることです。バグの多いhttpエージェントをハックするかもしれませんが、実際の解決策は、それらに対してではなく、キャッシュメカニズムを使用することです。 –
これは理想的ではなく、実際の解決策でもないことに同意しますが、Mozillaは実際にこれを回避策として推奨しているので、ひどすぎてはなりません- https://developer.mozilla。 org/en-US/docs/DOM/XMLHttpRequest/Using_XMLHttpRequest
その上、私はこれを解決しようとして私の髪を引き裂いていました。私は、ユーザーがブラウザをクリアすることをユーザーに頼らなければなりませんでした(ユーザーは、忘れてしまいます)。これは私にとって天の恵みです!