配列に格納したXHRのreadyStateを参照した結果、全て同じ値になってしまう問題の回避方法

このQ&Aのポイント
  • JavaScriptで複数のHTMLファイルの更新日時を調べる必要がありますが、readyStateで参照すると全て同じ値になってしまいます。
  • この問題を回避する方法として、リクエストごとにコールバック関数を作成し、その中で個別の値を参照することが必要です。
  • 具体的には、requestオブジェクトを配列ではなく、個別の変数として宣言し、forループ内でそれぞれのリクエストごとに別々のコールバック関数を設定することで解決できます。
回答を見る
  • ベストアンサー

配列に格納したXHRのreadyStateを参照

複数のHTMLファイルの更新日時をJavaScriptで調べる必要があり(サーバ側では仕様上できません)以下のように書いたのですが、readyStateで参照すると全てurls[2]の値になってしまいます。(つまり「/infomation/index.html」の更新日時)どのように回避すればよいのでしょうか。 onload=function () { var urls = new Array(3); urls[0] = "/about/index.html"; urls[1] = "/news/index.html"; urls[2] = "/infomation/index.html"; var request = new Array(); for(i=0;i<urls.length;i++){ request[i] = new XMLHttpRequest(); request[i].open("GET", urls[i]); request[i].send(null); request[i].onreadystatechange = function () { if (request[i].readyState == 4) { var lmdfd = request[i].getResponseHeader("Last-Modified"); 以下、更新日時の確認処理 } } } }

質問者が選んだベストアンサー

  • ベストアンサー
  • notnot
  • ベストアンサー率47% (4848/10262)
回答No.1

function () { if (request[i].readyState == 4) { ここの i のスコープを考えると、forのところの i ですが、この無名関数が呼ばれる時点で i は 2 になっていますので、毎回 request[2].readyState を参照するというのはその通り。 request[i].onreadystatechange = (function(x) {return function () { if (request[x].readyState == 4) { var lmdfd= request[x].getResponseHeader("Last-Modified"); 以下、更新日時の確認処理 } })(i);

furnace
質問者

お礼

ご回答をいただいた上に改善案まで示していただき、ありがとうございます。 処理が行われる順序についてや、 こうした書き方を見ること自体がはじめてで、勉強不足を感じざるをえません。 調べてみたいと思います。

関連するQ&A

  • readyState確認後の処理ができない

    jQueryによるajaxを試みています。checkboxにチェックを入れたときに動作するようにしたいので、以下のように書いているのですが、alertが動作しません。onreadystatechange = function(){より前に入れたalertは動作するので、イベントハンドラ?としては機能しているようなのですが、onreadystatechangeにひもづけている関数の書き方に問題があるのでしょうか? $(function(){ $("#check:checkbox").click(function() { var xhr = new XMLHttpRequest(); xhr.open('GET', 'test.txt', true); xhr.onreadystatechange = function(){ if (xhr.readyState == 4) { alert("OK"); } }; }); });

    • ベストアンサー
    • AJAX
  • 配列に格納した値が保存されない

    DB(Access)から取得した内容を配列に格納し、その内容を取り出すプログラムを 以下のように書いてみました。 whileループ内の alert("ループの中=" + data_array[i]); では配列の中の値が参照できるのですが whileループの外で for(var i=0;i < data_array.length; i++){ alert("ループの外:" + data_array[i]); } 配列の中身を表示させようとしたところdata_array.length の長さが0になっており 配列の中身が参照できない状態です。なにが原因かわかりますでしょうか。 <html> <script language="javascript" type="text/javascript"> function dbSearch() { var sql="select * from URL where flg=0"; var database = dbConnect(); var recordSet = database.Execute(sql); var data_array = new Array(); while (!recordSet.EOF){ data_array[i] = recordSet(0); alert("ループの中=" + data_array[i]); recordSet.MoveNext(); } alert("長さ=" + data_array.length); for(var i=0;i < data_array.length; i++){ alert("ループの外:" + data_array[i]); } database.Close(); return; } //データベースに接続 function dbConnect() { var database = new ActiveXObject("ADODB.Connection"); database.Open("Driver={Microsoft Access Driver (*.mdb)}; DBQ=c:\\test.mdb;"); return database; } </script> <body> <input type="button" value="DB接続" onclick="dbSearch()"> </body> </html>

  • Ajaxによる非同期通信のイベントリスナ

    JavaScriptで以下の関数を実行した場合、(1)の実行後関数を抜けるので、 (2)のイベントリスナは(1)の実行後も呼ばれることはあるのでしょうか。    function hoge(){     var xhr = new XMLHttpRequest();     xhr.open("GET","http://www.example.com/data.txt");     xhr.onreadystatechange = function(){ //(2)      if(xhr.readyState == 4 && xhr.status == 200){       $("#foo").html(xhr.responseText);      }     }     xhr.send(null); //(1)    } ローカル変数xhrは、関数を抜けたら変数とその領域が解放されるので、 XMLHttpRequestインスタンスも消滅する、そして、インスタンスが 消滅してしまうと、onreadystatechangeプロパティも消滅すると思っ たためです。 (2)が(1)の実行後も呼ばれるとしたら、どのような仕組になっていると 理解すればよいのでしょうか。

  • Yahoo!ウィジェットのgetElementsByTagName

    Yahoo!ウィジェットについて質問です。 getElementsByTagNameで取得したタグのlenghtはかえってくるのですが, tagNameのデータを読み込もうすると、(TypeError: unit[0] has no properties)になります。 Yahoo!ウィジェットのgetElementsByTagNameは、通常のJavaScriptとは違うのでしょうか? コードは以下の通りです。 ■JavaScript //XMLHTTPRequest var request = new XMLHttpRequest(); request.autoRedirect = false; request.open( "GET", "hoge.xml", true ); request.send(); request.onreadystatechange = myStatusProc; //XMLデータの表示 function myStatusProc(){ if ( this.readyState == 4 ){ var XMLObj = request.responseXML; var unit = XMLObj.getElementsByTagName("unit"); var a = unit[0].getElementsByTagName("a")[0].firstChild.nodeValue; print(a); } } ■XML <root> <unit> <a>test</a> </unit> <unit> <a>test</a> </unit> <unit> <a>test</a> </unit> </root> すみません。よろしくお願いします。

  • javascriptでの値の取得について

    すごく素人だと思うのですが。 この手のタイプで得られる値を外部で取得できないのでしょうか? 戻り値で返すわけにもいかないですし、よく理解できていません var val: ○.○=function(){ここで得た値をvalに入れたい} 例1 var target; ・・・ request.onreadystatechange=function(){ if(request.readyState==4 && request.status==200){ //target=request.responseText;みたいなことをしたい } } 例2 var width,height; ・・・ image.onload=function(){ //width=image.width; height=image.height;みたいなことをしたい }

  • xmlから配列で取得したものを取り出したい

    as3初心者jpncan15といいます。 xmlから配列で取得したものをfunction外で取り出したいのですがどのようにすればいいのか悩んでいます。functionを調べたり配列を調べたり頭がかなり混乱中です。 お手数ですがご教授いただけますでしょうか? var ary:Array=new Array(); var ary_name:Array=new Array(); var loader:URLLoader = new URLLoader(); var request:URLRequest = new URLRequest("b.xml"); var xml:XML; loader.load(request); loader.addEventListener(Event.COMPLETE , XMLload); function XMLload(e:Event):void { xml = XML(e.target.data); num_txt.text = xml.item.length(); //xml件数をテキストフィールドへ入れる for each(var element:Object in xml.item.thumb) //配列に入れる {ary.push(element);} for each(var element_name:Object in xml.item.name) //配列に入れる {ary_name.push(element_name); trace(element_name);}//出力OK } //function外で配列を使用したい trace(ary[5]); trace(ary_name[2]);

    • ベストアンサー
    • Flash
  • Ajaxのプログラムをオブジェクト指向で・・・

    Ajaxのプログラムを一つのオブジェクトにまとめてみようと思ってやってみたのですが、 >エラー: プロパティ 'readyState' の値を取得できません: オブジェクトは Null または未定義です。 などと表示されて上手く行きません。 何が悪くてエラーが出るのかが理解出来ていません。 詳しい方、エラーの原因・解決方法を教えてください。お願いします。 php側 echo "test"; javascript側 //-------------------------------------------------------------------- // てすとオブジェクト //-------------------------------------------------------------------- var Test = function() {// メンバ変数の定義 this.request = ""; this.query = "test";// クエリ this.response = "";// レスポンス }; Test.prototype = {// プロトタイプの定義 /* データ送信 */ tSend : function() { if(this.query) { this.request = this.ajaxRequest(); this.request.onreadystatechange = this.tLoad; if(this.query) { this.request.open("POST", "./index.php", true); this.request.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); this.request.send(this.query); } } }, /* データ受信 */ tLoad : function() { if((this.request.readyState == 4) && (this.request.status == 200)) { alert("test"); } }, /* HTTP通信用 */ ajaxRequest : function() { var value = null; try { value = new XMLHttpRequest(); } catch(e) { try { value = new ActiveXObject("Msxml2.XMLHTTP"); } catch(e) { try { value = new ActiveXObject("Microsoft.XMLHTTP"); } catch(e) { return null; } } } return value; } }; //----------------------------------------------------------------------- // 実行 //----------------------------------------------------------------------- var Test = new Test();// 通信用オブジェクトの生成 Test.tSend();// データ送信

  • textarea内のxmlデータを読み込みたい

    javascriptでxmlのファイルを読み込む時には var request = GXmlHttp.create(); request.open("GET", "hogehoge.xml", true); request.onreadystatechange = function() { if (request.readyState == 4) { : とか書くと思うのですが、ファイルからではなくtextarea内にある xmlフォーマットで入力されたデータを読み込むにはどのように したらいいのでしょうか?

    • 締切済み
    • XML
  • readyStateが4にならない原因

    apache2でAjaxの試しとして下記スクリプトだけのhtmlファイル(http://localhost/newfile.html)を 作り動作を確認してみました(空白部分は全角になっています)。すると最後の部分の alert("Error: readyState code is " + request.readyState);で 2→アラートのOKを押す→一瞬1になり3→アラートのOKを押す→一瞬1になり0→アラートのOKを押すと1になりました。そしてコンソールには ------------------------------------------------ GET http://localhost/a.php 200 OK 60ms Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) request.send(url); ------------------------------------------------ といったエラー表示がでてしまいます。 また、request.openで渡すURLの「http://localhost/a.php」を「a.php」にすると、 一瞬1になり2→アラートのOKを押す→一瞬1になり0→アラートのOKを押すと1 になります。なぜ4にならないのでしょうか。 request.statusは全部0になっているようです。 <script language="javascript" type="text/javascript"> var request = false; try {   request = new XMLHttpRequest(); } catch (trymicrosoft) {   try {     request = new ActiveXObject("Msxml2.XMLHTTP");   } catch (othermicrosoft) {     try {       request = new ActiveXObject("Microsoft.XMLHTTP");     } catch (failed) {       request = false;     }   } } if (!request)   alert("Error initializing XMLHttpRequest!"); window.onload = getCustomerInfo; function getCustomerInfo() { var url = "test"; request.open("GET", "http://localhost/a.php", true); request.onreadystatechange = updatePage; request.send(url); } function updatePage() { if (request.readyState == 4){ if(request.status == 200){     var response = request.responseText;          document.write(response); }else  if (request.status == 404){   alert("Request URL does not exist");      }else{      alert("Error: status code is " + request.status); } }else{   alert("Error: readyState code is " + request.readyState); } } </script>

    • ベストアンサー
    • AJAX
  • CGIを呼び出した場合の戻り値をDOMオブジェクトにする

    var rtn; var obj = new XMLHttpRequest(); obj.open("GET","/test.xml"); obj.setRequestHeader(~略~); obj.send(""); obj.onreadystatechange = function( ){   if(obj.readyState == 4){     rtn = obj.responseXML);   } } この場合のrtnの値はtext.xmlのDOMオブジェクトとなりますが、 これを、 var obj = new XMLHttpRequest(); obj.open("GET","/test.cgi"); obj.send(""); とし、cgiからの戻り値としてDOMオブジェクトを受けることは可能ですか? やはりcgiからプログラムを通じてxmlファイルを作成し、 それをもう一度、 obj.open("GET","/test.xml"); obj.send(""); として読み込むしかないでしょうか?

専門家に質問してみよう