名前を入れて送信ボタンを押してください。名前は非同期にサーバに送られ,サーバからは挨拶と現在のUNIX時刻(1970年元旦からの秒数)が返されます。ページ全体を読み直すわけではないので,たいへん高速です。
まずはこのページのソースをご覧ください(エンコーディングはUTF-8です)。headの中の
<script> …… </script>
の部分がJavaScriptのプログラムです。ここでは,そのずっと下のformの部分から見ていきましょう。
<form onsubmit="doit();return false;"> <p>お名前:<input id="user"> <input type="submit" value="送信"></p> </form> <div id="result"></div>
このformに書き込んで「送信」ボタンを押すと,onsubmit
で指定されている doit(); return false; が実行されます。ここで return false; はブラウザの標準の動作(この場合formのsubmitボタンの動作)をさせないための常套手段です。doit() の定義は次のようになっています(多少簡略化しましたが後で説明します)。
<script>
function doit() {
const req = new XMLHttpRequest();
if (req == null) {
document.getElementById("result").innerHTML = "<p>未対応ブラウザです。<\/p>";
} else {
req.onreadystatechange = function() {
if (req.readyState == 4 && req.status == 200) {
document.getElementById("result").innerHTML = req.responseText;
}
};
const u = encodeURIComponent(document.getElementById("user").value);
req.open("POST", "ex1.php", true);
req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
req.send("user=" + u);
}
}
</script>
まず,新しい XMLHttpRequest
オブジェクト(サーバと非同期通信するための仕組み)を生成し,それを req
という変数に代入しています。
これに失敗すれば(req == null なら),<div id="result"></div>
の中に <p>未対応ブラウザです。</p>
というHTMLを書き込むだけで終わります。
失敗しなければ,req というオブジェクトの onreadystatechange
というプロパティ(JavaやC++の用語ではフィールド)に無名の関数を代入しています。
この関数はコールバック関数と呼ばれ,何かイベントが発生すると呼ばれます。
ここでは req というオブジェクトが作業を遂行するにつれ,その状態 req.readyState
が0→1→2→3→4と変化するのですが,その変化のたびに呼ばれる関数を定義しています。
作業が完遂されたなら req.readyState == 4
になりますが,そのときのHTTPステータスコード req.status
が200(OK)ならば,サーバから送られたテキスト req.responseText
を <div id="result"></div>
の中に表示します。
続いて,<input id="user">
の値(つまりユーザが打ち込んだお名前)を取り出し,これをURLエンコード(アスキー以外の文字を %
に続く16進2桁に直すこと)して,それを変数 u に代入しています。
続いて,req.open で,POSTメソッドでサーバの ex1.php
を呼び出しています(最後の true は非同期呼出しを意味します)。
このPOSTメソッドでは Content-Type: application/x-www-form-urlencoded
というヘッダを使います。
最後に,user= に続けてさきほどのURLエンコードした値を送ります。
これで doit() 関数は終わりますが,コールバック関数が設定されていますので,上に述べたように,状態が変わればそちらのほうが呼び出されることになります。
サーバ側には,この ex1.html と同じディレクトリに次の ex1.php というファイルがはいっています:
<?php
header('Content-Type: text/html; charset=UTF-8');
if ($_POST['user']) {
echo '<p>', htmlspecialchars($_POST['user']), 'さんこんにちは。</p>';
}
echo '<p>だたいまのUNIX時刻は ', time(), ' 秒です。</p>';
?>
これは,POSTメソッドで受け取った user の値を htmlspecialchars()
で無害化(< を < に直すなど)してから挨拶に直して,現在のUNIX時刻(1970年元旦からの秒数)とともに送り返します。
この場合 if ($_POST['user']) は user=...
がセットされていて,なおかつ空文字列 "" でも "0"
でもないことを意味します。もし 0 と打ち込まれたら空欄と判断されてしまいますので,厳密には if (isset($_POST['user']) && $_POST['user'] != '') とすべきかもしれません。