非同期通信(JavaScript : XMLHttpRequest, jQuery : ajax)

(ブログ記事の一覧は「こちら」)

Webアプリにおける非同期通信(Ajax)とは、複数の処理を同時に行うように見せかけて行うことのできる処理と言えます。(JavaScriptの非同期通信はシングルスレッドで行われます。)
ある処理が終わるのを待たずに別の処理が終了することが実現できるので、例えば、画面の遷移をせずにHTMLを更新することが可能になります。

参考:

AJAX PHP(w3schools.com)
AJAX Database(w3schools.com)

非同期通信のプログラムの書き方

JavaScriptでの記述例

var strUrl = "xxx.php";
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
    // 非同期通信(Ajax)
    // readyState 4: リクエスト終了, status 200:通信成功
    if (this.readyState == 4 && this.status == 200) {
        console.log(this.responseText);
    }
}
xmlhttp.open("GET", strUrl, true);  // 第3引数の意味(非同期通信:true、同期通信:false)
xmlhttp.send();

非同期通信(Ajax)を行うには、JavaScriptXMLHttpRequest オブジェクトを使用します。

jQueryでの記述例

$.ajax({
    type: "GET",
    url: "xxx.php"
}).done(function(data) {
    console.log(data);
}).fail(function(data) {
    alert("error");
});

jQueryでは、$.ajax 関数を使用します。JavaScriptの場合と比べると、少ないコードで書けることがわかります。

サンプルプログラム

このサンプルは、画面の遷移をせずに(つまり、別のURLにアクセスすることなしに)PHPプログラムでのデータベースのアクセスが可能になります。

非同期通信(Ajax)で呼び出される側のPHPプログラムは、PHPからデータベースを操作(データの抽出、検索)の例題2で説明した「searchFoodName_receive_pdo.php」を使用することにします。(結果をわかりやすくするために、出力にpriceを追加しています)

<?php
    require_once('./dbConfig.php');

    $name = $_GET['name'];
    if (empty($name) == true) {
        die("'name'の設定なし");
    }

    // 接続
    try {
        $dsn = 'mysql:host=' . DB_SERVER . ';dbname=' . DB_NAME . ';charset=utf8';
        $pdo = new PDO($dsn, DB_USER, DB_PASS);
    } catch (PDOException $e) {
        die("接続に失敗しました" . $e->getMessage());
    }

    // レコード検索
    $sql = "SELECT * FROM fruits_list WHERE name=:name";
    $stmt = $pdo->prepare($sql);
    $stmt->bindValue(':name', $name, PDO::PARAM_STR);
    $stmt->execute();

    echo "<ul>";
    foreach($stmt as $row) {
//     echo "<li>" . $row['name'] . "</li>";
        echo "<li>" . $row['name'] . " " . $row['price'] . "</li>";
    }
    echo "</ul>";

    $pdo = null;
?>


非同期通信(Ajax)を行うサンプルプログラムです。「getFoodName_ajax.html」として作成します。

JavaScriptでの記述例

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script>
function callGetFoodName() {
   var strText = document.myform.mytext.value;
   getFoodName(strText);
}

function getFoodName(str) {
   if (str.length == 0) {
       document.getElementById("txtResult").innerHTML = "";
       return;
   } else {
       var strUrl = "searchFoodName_receive_pdo.php?name=" + str;
       // HTTP通信
       var xmlhttp = new XMLHttpRequest();
       xmlhttp.onreadystatechange = function() {
           // 非同期通信(Ajax)
           // readyState 4: リクエスト終了, status 200:通信成功
           if (this.readyState == 4 && this.status == 200) {
               document.getElementById("txtResult").innerHTML = this.responseText;
           }
       }
       xmlhttp.open("GET", strUrl, true);
       xmlhttp.send();
   }
}
</script>
</head>

<body>
    <h1>非同期通信(Ajax) サンプル</h1>

    <form name="myform">
        <p><input type="text" name="mytext"></p>
        <p><input type="button" value="送信" onclick="callGetFoodName()"></p>
    </form>

    <p>結果: <span id="txtResult"></span></p>
</body>
</html>

HTMLのボタンは、submitではなくbuttonを指定します。(submitを指定すると、結果の表示がうまくいかない症状が起こります。)

jQueryでの記述例

<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script>
$(function() {
    $("#callGetFoodName").on("click", function() {
       var strText = document.myform.mytext.value;
       getFoodName(strText);
    });
});

function getFoodName(str) {
   if (str.length == 0) {
       $("#txtResult").html("");
       return;
   } else {
       var strUrl = "searchFoodName_receive_pdo.php?name=" + str;
       // HTTP通信 API
       $.ajax({
           type: "GET",
           url: strUrl
       }).done(function(data) {
           $("#txtResult").html(data);
       }).fail(function(data) {
           alert("error");
       });
   }
}
</script>
</head>

<body>
    <h1>非同期通信(Ajax) サンプル</h1>

    <form name="myform">
        <p><input type="text" name="mytext"></p>
        <p><input type="button" id="callGetFoodName" value="送信"></p>
    </form>

    <p>結果: <span id="txtResult"></span></p>
</body>
</html>

実行、確認

以下をWebブラウザで実行します。 名前を入力して、送信ボタンを押すと、名前が一致するテーブル内のレコードの一覧が表示されます。

http://localhost/sample/food/getFoodName_ajax.php