質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.35%

javascriptでhttpステータスコードを取得

受付中

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 9,366

kachan777

score 19

お世話になります。

javascriptをローカルのブラウザで動作させて
対象のwebサーバからhttpのステータスコードを取得、
200か否かで表のSTATUS欄の色と文言を変化させたいです。

※クロスドメイン制限はブラウザで解除

xhr.onreadystatechange実行時にif文で

resultにOKかNG
bg_colorに表示する色

を代入していますが、
その後のdocument.writeにうまく反映されません。
(undefinedになってしまう)

ご教授願います。

<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">

    <script language="JavaScript" type="text/javascript">
      // 自動更新のリロード時間
      //setTimeout("location.reload()",1000*60);

      // DUMY SERVERURL
      var base_url = "http://XXX.XXX.XXX.";

      // DUMY SERVERの数
      var max = 15;
    </script>

  </head>

  <body>

    <script language="JavaScript" type="text/javascript">
      document.write("<table border=\"3\">");
      document.write("<tr bgcolor=\"Aqua\"><th>DUMY SERVER</th><th>STATUS</th></tr>");

      var ip = 10;

      for(var i = 1 ; i <= max ; i++) {

        ip++;
        var url = base_url + ip;
        var server = "SAVEDUMY" + i;

        var result;
        var bg_color;

        var xhr = new XMLHttpRequest();
        xhr.open('GET', url, true);

        xhr.onreadystatechange = function(){
          if (xhr.readyState === 4 && xhr.status === 200){
            //console.log("200");
            result = "OK";
            bg_color = "Lime";
          }else{
            result = "NG";
            bg_color = "Red";
          }
        };

        xhr.send();

      document.write("<tr><td>" + server + "</td><td bgcolor=\"" + bg_color + "\">" + result + "</td></tr>");
      }

      document.write("</table>");
    </script>

  </body>

</html>
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

+1

xhr.onreadystatechange = function(){
          if (xhr.readyState === 4 && xhr.status === 200){
            //console.log("200");
            result = "OK";
            bg_color = "Lime";
          }else{
            result = "NG";
            bg_color = "Red";
          }
        };


の中で確実にresultとbg_colorに値が入っていますか?
プログラムのミスやエラーの原因を探る基本的な方法として、console.log()で、処理がどこを通っているかを確認してみるといいと思います。

ちなみにIE11で試したらred,NGがそれぞれ入り、Firefoxだと両者ともundifinedになりました。
クロスオリジン要求が通らずそもそもgetできていない感じです。

※クロスドメイン制限はブラウザで解除
とありますが、これがうまくいっていないのではないでしょうか?

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

XMLHttpRequest は非同期通信なので、onreadystatechange を定義した直後の document.write は高確率で undifined になります。描画処理は onreadystatechange に代入している関数内で行うのが良いでしょう。

また、document.write は記述場所と実行タイミングによって描画位置が変わる場合があるため、今回のコードであれば "</table>" の後に "<tr><td>"・・・ が出力される可能性があります。


追記:

未テストですが、書くならこういう感じという参考になれば幸いです。
for の中の var を削除したのは、for は var ではスコープを持たないためです。(letなら意図通りになるかも)

var $body = document.querySelector( 'body' );
// tableをbodyに追加
$body.insertAdjacentHTML( 'beforeend', '<table border="3" id="my_table"><tr bgcolor="Aqua"><th>DUMY SERVER</th><th>STATUS</th></tr></table>' );
var $table = document.getElementById( 'my_table' );
var ip = 10;
var i, url, server;
for ( i = 1 ; i <= max ; i++) {
    ip++;
    url = base_url + ip;
    server = 'SAVEDUMY' + i;
    ( function () {
        var xhr = new XMLHttpRequest();
        xhr.open( 'GET', url, true );
        xhr.onreadystatechange = function() { // ここの中で server などの変数を使うために即時関数を利用しています。
            var result, bg_color;
            console.log( xhr.status );
            if ( xhr.readyState === 4 && xhr.status === 200 ) {
                result = 'OK';
                bg_color = 'Lime';
            } else {
                result = 'NG';
                bg_color = 'Red';
            }
            // tableに行を追加
            $table.insertAdjacentHTML( '<tr><td>' + server + '</td><td style="background-color:' + bg_color + ';">' + result + '</td></tr>' );
        };
        xhr.send();
    } )( url, server ); // 即時関数
}

【JavaScriptのスコープとクロージャとletステートメント - Qiita】
http://qiita.com/yaegaki/items/704f547afca7a09ad131

【JavaScriptで即時関数を使う理由 - Qiita】
http://qiita.com/katsukii/items/cfe9fd968ba0db603b1e

【document . writeはやめて、innerHTMLを使おう | Web Developers Antenna ?ウェブ開発者アンテナ? [W'ANEB]】
http://web.antenna.work/innerhtml/

【innerHTMLの代わりにinsertAdjacentHTML()を使ってみようか。(DOMおれおれAdvent Calendar 2015 ? 01日目) | Ginpen.com】
http://ginpen.com/2015/12/01/insertadjacenthtml-instead-of-innerhtml/

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/08/02 01:22 編集

    > $table.insertAdjacentHTML( '<tr><td>' + server + '</td><td style="background-color:' + bg_color + ';">' + result + '</td></tr>' );
    IE9- には innerHTML で table 要素ノードを書き換えられない仕様があります。
    https://blogs.msdn.microsoft.com/ie/2011/07/06/html5-parsing-in-ie10/
    MSは2017年4月11日まではIE9をサポートしています。
    IE9を動作対象に含めるならば、insertAdjacentHTML を使う事を前提とするなら、文字列処理で "<table>...</table>" を生成し、insertAdjacentHTML で <table> を挿入するといいと思います。
    もしくは table API でゴリゴリやってもいいですね。
    http://www2u.biglobe.ne.jp/~oz-07ams/2003/HTML/index.html#ID-798055546-h3

    キャンセル

  • 2016/08/02 02:47

    いつも指摘ありがとうございます!
    IE9を(ほぼ)無視できるまであと1年切ったんですね・・・感慨深いです。

    > もしくは table API でゴリゴリやってもいいですね。
    追加のたびにテーブルを削除するのがあまり美しく無い気がするので、IE9が対象に入るならこちらでしょうね。(通信が終わるまで待って一括で、もできますがそのためにコードを増やすのもあれなので)

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.35%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る