COM(XMLHTTP)オブジェクトの挙動についてNo.05787
たけとり さん 10/06/08 08:06
 
 いつもお世話になります。
 開発&サポート、お疲れ様です。

 さて、最近あるブログサイト向けのマクロを作っているのですが、その中で不可解
な事例が発生したので、投稿します。
 お忙しいところ恐縮ではございますが、何か心当たりみたいなものがあれば教えて
いただけたら幸いです。
(秀丸8.01 β2, WindowsXP SP2)

 まずマクロは、以下のような感じです。(エラー処理とか省いています。なお、kee
pobjectは使っていません。)

 ##xmlhttp = createobject("Msxml2.XMLHTTP.3.0");
 callmethod ##xmlhttp, "open", "GET", "http://〜", 0;
 callmethod ##xmlhttp, "setRequestHeader", "X-WSSE", "ABCD...";  //***
 callmethod ##xmlhttp, "setRequestHeader", "Content-Type", "text/xml";
 callmethod ##xmlhttp, "send", "";
 insert getpropstr(##xmlhttp, "responseText");
 releaseobject ##xmlhttp;
 endmacro;

 これは、ブログサイトに投稿されたブログの内容を取得するコードです。
# ***行(3行目)ですが、
#  取得に当たっては特定のURI(いわゆるWebAPI)にGETで接続する必要があり、その
際には、パスワードなどから生成(SHA1アルゴリズムでダイジェスト化)した文字列を
HTTPのX-WSSEヘッダに設定しています。
#  なお、この文字列は本来なら接続のたびに生成しそのたびに異なる値になる文字
列ですが、ここではテストのために同一の文字列を利用しています(ちなみに、接続
のたびに生成していた場合でも下記事例は発生しました)。

 不可解な事例が出現する手順というのは、以下のようなものです。

<1> 任意の秀丸(任意のタブ。タブA)で当該マクロを実行して、ブログの内容を取得
する―→正常に取得できる。
<2> ブラウザなどでブログを編集(新規に追加or既存の内容を修正or削除のいずれで
も)。
<3> もう一度タブAで当該マクロを実行して、ブログの内容を取得する―→取得でき
るデータは<2>で編集されたものが反映されていない(<1>で取得したものと同じ内容
を取得する)。

 つまり、実際にデータが変わっているにもかかわらずマクロで取得できるデータは
古いままである、というものです。
#  なお、XMLHTTPのバージョンを変えてみても同様でした。
# <1>と<3>をそれぞれ別バージョンでやっても同様です。

 これだけだと、ブログサイト・マクロ側のバグも考えられますが、
・<3>でマクロの代わりに別のプログラム(wget)で同一のX-WSSEヘッダとともにGET接
続―→新しい内容(<2>での編集を反映した内容)を取得。
・<1>をしない場合―→<3>において、新しい内容を取得。
・<2>と<3>の間でタブAにて「ファイル名変更」や「名前をつけて保存」する―→<3>
において、新しい内容を取得。
という現象も確認できています。

 さらに、先の<3>に引き続いて、

<4> 別の秀丸(別のタブ)を立ち上げてそこでマクロ実行―→新しい内容(<2>で編集さ
れた内容)を取得。
<5> タブAに戻り、そこでもう一度マクロ実行―→新しい内容(<2>で編集された内容。
<4>で得られるものと同一)を取得。

 つまり、先ほどまで古いデータしか取得できなかったにもかかわらず、別の秀丸で
実行したらそこでは最新のデータを取得でき、さらに(古いデータしか取得できない
でいた)元の秀丸で取得できる内容も新しいデータになっている、というものです。

 よろしくお願いします。
#  正しくマクロも終了しているし、releaseobjectもソース中にあるのですが、も
しかしてオブジェクトが残っていたり...などと愚考しています。(^^;
#  ただ##xmlhttpの代わりに「1」とか「2」とか、以前オブジェクトを呼び出した
時に得られた番号を直接指定しても、メソッドもプロパティも反応しません。

[ ]
RE:05787 COM(XMLHTTP)オブジェクトの挙動No.05789
秀丸担当 さん 10/06/08 10:44
 

改めてソースを確認してみましたが、解放は行われているようです。

試しに VBSでhttpリクエストを2回連続で行うものを作ってみたところ、同じよ
うな現象が確認できました。
2回連続では、2回目がキャッシュになるようです。
連続リクエストの間にメッセージボックスを挟んで、メッセージが出ている間に
別のプロセスで同じリクエストして、元のプロセスで続行、というようにしたら、
元のプロセスの2回目は新しいデータでした。

適当にWeb検索してみたところ、キャッシュを無効にするリクエストをするとい
いようです。
例:
 callmethod ##xmlhttp, "SetRequestHeader", "If-Modified-Since", "Thu, 01
Jun 1970 00:00:00 GMT";


「Cache-Control: no-cache」とか「Pragma: no-cache」などの方法もあるらし
いですが、試してみた限りではなぜかうまくいかず、If-Modified-Sinceでやる
のが効果があるようです。

[ ]
RE:05789 COM(XMLHTTP)オブジェクトの挙動No.05790
たけとり さん 10/06/09 07:28
 
 早々のご回答、ありがとうございます。

>2回連続では、2回目がキャッシュになるようです。

 キャッシュ...。まさかそんなことがあるなんて...考えてもなかったです。
 失礼しました。

>適当にWeb検索してみたところ、キャッシュを無効にするリクエストをするとい
>いようです。

 早速対策してみました。
 結論から言うと、If-Modified-Sinceを用いた方法で、ばっちり反映されました。
 そして、同様にCache-ControlやPragma(だけ)を用いた方法ではうまくいきませ
んでしたが、必要になる場合もあるらしいので、念のため対策をしておきました。
(Cache-Controlは「no-cache, no-store, must-revalidate, post-check=0, pre-che
ck=0」という指定でもだめでした。)

 ということで、おかげさまで無事に動くようになりました。
 ありがとうございます。
 また何かありましたら、よろしくお願いします。

[ ]