名前を入れて送信ボタンを押してください。名前は非同期にサーバに送られ,サーバからは挨拶と現在の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'] != '')
とすべきかもしれません。