メモ書き JavaScript

2005/12/01
■Ajaxなるものをやってみる

私のホームページ内に毎回cgiで表示を行っているページがある。
サーバ負担を減らそうと、Ajaxなるものを利用しようと考えた。
具体的にはページを更新する必要があるときにだけcgiを起動してhtmlを作成し、通常はその作成したhtmlを表示する、 というものである。

とりあえず、どんなものなのか探りを入れる。

<html>
<head>
<script type="text/javascript">
<!--
function testAjax() {
    // XMLHTTPオブジェクト作成
    var req;
    if(window.XMLHttpRequest) { // IE以外
        req = new XMLHttpRequest();
    } else if(window.ActiveXObject) { // IE
        try {
            req = new ActiveXObject("Msxml2.XMLHTTP");
        } catch(e) {
            req = new ActiveXObject("Microsoft.XMLHTTP");
        }
    }


    //ブラウザのキャッシュ対策
    var dummy = (new Date()).getTime();

    var url = "http://localhost:8080/myworks/abc.txt?" + dummy;
    var objId = "idRet";

    req.open("GET", url, true); //true:非同期通信
    req.onreadystatechange = function() { //状態が変更されたらこの関数を呼ぶ
        if (req.readyState == 4 && req.status == 200) {
            document.getElementById(objId).innerHTML = req.responseText;
        }
    }
    req.send(""); //送信(引数はPOST用)
}
//-->
</script>
</head>
<body>

    <div id="idRet">ここにファイルの内容を読み込みます</div>
    <input type="button" name="name" value=" click " onclick="testAjax();">

</body>
</html>

ここにファイルの内容を読み込みます


ページの遷移(更新)を行わずに、指定した場所のテキストを変更することが出来た。
Ajaxは基本的に非同期でXMLを扱うものらしい。

req.setRequestHeader("If-Modified-Since", "Thu, 01 Jun 1970 00:00:00 GMT");
を使うことでキャッシュの防止ができるが、Opera8.5で動かしたらうまくいかなかった。
Operaの場合はsetRequestHeaderがないらしい。
そのため、ダミー文字列を連結してアドレスを毎回変えることでキャッシュ対策をしている。


で、今回やりたいことは、
1.ページ更新が必要かどうか判断するためのテキストファイルを読みに行く。
2.必要ならcgiを起動、htmlを作成し、1のテキストファイルを書き換える。
といった流れ。
コードを書くと、

<div id="id01">id01</div>
<div id="id02">id02</div>
<div id="msg">msg</div>

<script type="text/javascript">
<!--
//-------- 初期化 --------
var date = new Date();

//今日の日付取得
var YYYY = date.getFullYear();
var MM   = date.getMonth() + 1;
var DD   = date.getDate();
if (MM < 10) MM = "0" + MM;
if (DD < 10) DD = "0" + DD;
var today = YYYY.toString() + MM.toString() + DD.toString();

//ブラウザのキャッシュ対策
var dummy = date.getTime();

var req;
var cgiflag = false;
var serverday = today;

//-------- XMLHTTPオブジェクト作成 --------
if(window.XMLHttpRequest) { // IE以外
    req = new XMLHttpRequest();
} else if(window.ActiveXObject) { // IE
    try {
        req = new ActiveXObject("Msxml2.XMLHTTP");
    } catch(e) {
        req = new ActiveXObject("Microsoft.XMLHTTP");
    }
}

//-------- txtアクセス --------
var url = "http://localhost:8080/myworks/abc.txt?" + dummy;
var objId = "id01";

req.open("GET", url, false); //同期通信(false)
req.send("");


if (req.status==200) {
    document.getElementById(objId).innerHTML = req.responseText;
    serverday = req.responseText;
} else {
    alert("失敗");
}

//-------- CGIアクセス --------
//クライアントの日付とhtmlの最終更新日付が違った場合にcgiを起動してhtmlを作成
//ユーザによるデータ更新が合った場合は、最終更新日付を書き換えておく。
//クライアントの日付が合ってない場合は毎回cgiアクセスしてしまうが、htmlの作り直しは防げる。 if (serverday != today) {
    var url = "http://localhost:8080/myworks/cgi-bin/test1201.cgi?" + dummy;
    var objId = "id02";
    
    req.open("GET", url, false);
    req.send("");
    
    if (req.status==200) {
        document.getElementById(objId).innerHTML = req.responseText;
        cgiflag = true;
    } else {
        alert("失敗");
    }
}

//-------- 更新 --------
if (cgiflag == true) {
    setTimeout("location.reload();", 5000);
    var objId = "msg";
    document.getElementById(objId).innerHTML = "データが更新されました。リロードします";
    tId = setInterval("document.getElementById('" + objId + "').innerHTML += '.';", 1000);
}

//-->
</script>

こんな感じ。
同期通信でXMLではなくテキストを使用。Ajaxの範囲からそれたか?
ちなみにローカル環境にTomcat入れて試しました。