1月 24 2010

loopでXMLHttpRequestを取得する

ブラウザ三国志用のGreaseMonkeyを作成していて詰まったところの備忘録。

再帰処理でXMLHttpRequestを行う。

XMLHttpRequestをfor loopで回しているとsendが行われたときにレスポンスは正常に取得しているのに、ステータスチェック後の処理が最後のリクエスト分にしか行われていないので調べたところ。

ステータスが4と200になる前に次のリクエストが走って、ステータスを上書きしてしまっているようだ。

現在の処理が終わってから次の処理を行うために、再帰処理に修正したらうまく取得できた。

並列で処理したい場合は、XMLHttpRequestオブジェクトを複数作成してあげればいけそうです。

responseXML、responseText

responseの辺りがよく分かっていない。

responseXMLだとDOMで取得できると思ったんだけど、パースエラーで取得できていなかったので、

きちんとしたHTML or XMLでないと取得できないのかな?

諦めて、responseTextで取得したのをパース用の関数で処理してみてもパースエラー
ベターな方法じゃないだろうけど、エレメントを作成してinnerHTMLとして挿入すると、XPathやgetElementで扱えるようになったので、これでヨシとしよう。


var url = new Array(); //URLを格納する配列
var counter = 0;       //ループ回数制御用のカウンタ
//XHR用の再帰処理
function xhr(){
//配列の中身が無くなったらreturnで抜けて、再帰処理を終了
if(!url[counter]){
return;
}
//XHR
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", url[counter]);
xmlhttp.send(null);
//ステータスチェンジで発生するイベント
xmlhttp.onreadystatechange = function(){
//XMLHttpRequestオブジェクトの準備の状態が4(準備完了)
if(xmlhttp.readyState ==4){
//リスクエストで帰ってきたステータスコードが200(正常)
if(xmlhttp.status == 200){
//xmlhttp.responseXMLでパースエラーがでたので、responseTextで取得して、
//新しく作った要素のinnerHTMLに突っ込むとXPathとかgetElementで処理できる。
var responseXML = document.createElement("div");
responseXML.innerHTML = xmlhttp.responseText;
//カウントアップ
counter++;
//再帰呼び出し
xhr();
}
}
}
}