Ajaxの説明とJQueryによる簡易実装

## 初めに
前の座席の同僚に「お前、Ajaxって知ってる？」と言われたことが悲しくて執筆に至ります。
本記事はAjaxに関する簡単な説明と処理の実装を目的としています。

## Ajaxとは
Ajaxとは、**「Asynchronous JavaScript + XML」**の略です。
直訳すると、「非同期のJavaScriptとXML」となります。
そもそも**非同期**とは何のことでしょうか。

### 同期通信と非同期通信
まず初めにブラウザとサーバのHTTP通信の基本的な流れについて説明します。

1. ブラウザ：サーバに対してリクエストを送信  
例：Google検索窓に「小松菜奈」と入力してクリック
2. サーバ：ブラウザからのリクエストを処理  
例：「小松菜奈」に関するデータを抽出し、良い具合に加工
3. サーバ：2の処理完了後、ブラウザにレスポンスを送信  
例：加工済み「小松菜奈」データを送信
4. ブラウザはレスポンスに基づき画面を描画する  
例：「小松菜奈」に関する検索結果が表示

以上のように、ブラウザとサーバ間ではリクエストとレスポンスのやり取りがされます。

1~4を一連の流れとしたとき、
**4まで完了しないと1の操作が不可能なものが同期処理**、
**4まで完了していなくても(任意のタイミングで)1の操作が可能なものが非同期処理**
です。

より簡単に言うと、
**・同期通信：通信が完了するまで次の処理を行うことができない通信**、
**・非同期通信：通信の途中でも他の処理を行うことができる通信**
となります。

### XML
ところで「Asynchronous JavaScript + XML」のXMLとは一体何のことでしょうか。
XMLは、**「Extensible Markup Language」**の略で、文章の意味や内容、構造をタグを用いて整理するマークアップ言語の一つです。他の代表的なマークアップ言語にはHTMLがあります。
Webページの見た目を整えるHTMLに対し、XMLは、機械に対して情報を伝達するのに長けていると言われています。
また、W3C（World Wide Web Consortium）によるオープンな規格であることから、多くのシステムに対する汎用性もあり、注目度の高い言語となっています。

### ここまでのまとめ
Ajaxとは、
**1. JavaScriptを用いて、**
**2. XML形式のデータを、**
**3. 非同期に通信する**
ことを実現する技術だと理解しておけばよいでしょう。

## Ajaxの実装例
### 環境
- macOS High Sierra 10.13.6
- JQuery 3.4.1
- PHP 7.1.16

それではAjaxを用いた簡単な処理を実装していきます。
まずはHTMLファイルから。

```html:index.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <!-- 今回はJQueryを用いてAjax通信を実現するため、GoogleのCDN経由でJQueryを読み込む -->
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
  <title>世界一美しいのは誰か</title>
</head>
<body>
  <form method="post">
    <p>世界で一番美しい人物の名前を答えなさい</p>
    <p>あなたの答え：<input type="text" name="answer" id="answer"></p>
  </form>
  
  <button id="ajax">Ajax通信</button>
  <div class="result"></div>
  
  <script>
    $(function(){
      // 「Ajax通信」ボタンをクリックしたら発動
      $('#ajax').on('click',function(){
        $.ajax({
          url:'./nana.php',
          type:'POST',
          data:{
            'answer':$('#answer').val()
          }
        })
        // Ajax通信が成功したら発動
        .done( (data) => {
          $('.result').html(data);
        })
        // Ajax通信が失敗したら発動
        .fail( (jqXHR, textStatus, errorThrown) => {
          alert('Ajax通信に失敗しました。');
          console.log("jqXHR          : " + jqXHR.status); // HTTPステータスを表示
          console.log("textStatus     : " + textStatus);    // タイムアウト、パースエラーなどのエラー情報を表示
          console.log("errorThrown    : " + errorThrown.message); // 例外情報を表示
        })
        // Ajax通信が成功・失敗のどちらでも発動
        .always( (data) => {
          if($('#answer').val() == '小松菜奈'){
            console.log('あなたは正しい');
          }else{
            console.log('あなたは間違っている');
          }
        });
      });
    });
  </script>
</body>
</html>
```
ソースコードのコメントをお読みいただくと理解が深まるかと思います。
console.logはよくデバッグに用いられるので、開発中にどの処理を通過しているのかを探るときに便利です。

次にPHPファイルです。

```php:nana.php
<?php
header('Content-type: text/plain; charset= UTF-8');
if(!empty($_POST['answer'])){
    $answer = $_POST['answer'];
    if($answer == '小松菜奈'){
        $result = $answer."は世界一美しい";
    }else{
        $result = $answer."は世界一美しいわけではない";
    }
    echo $result;
}else{
    echo '文字を入力してください';
}
?>
```

中身の処理はシンプルで、Ajaxで送信されたinput要素の値を$_POST['answer']で取得し、その値によって返すデータを変えています。

### 全体の流れ
ローカルサーバとしてPHPのビルトインサーバを用いました。
PHPがインストールされていれば、`php -S localhost:ポート番号`で立てることができます。
以下、通信が成功した例を示します。   
1. ~/index.htmlをブラウザで表示すると以下のようになる。
<img width="1440" alt="スクリーンショット 2019-10-04 18.59.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299210/822b83cb-4bc3-4eab-90fa-ace769c8ea2c.png">   
2. フォームに文字を入力し「Ajax通信」ボタンを押下。
ここで、入力した値がブラウザからサーバへ送信される。
<img width="1440" alt="スクリーンショット 2019-10-04 19.08.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299210/0ebfabab-d9ff-c4d6-6e1a-216a57514afa.png">   
3. 送信された値がnana.phpファイル内で処理され、加工された値が返却される。
※このnana.phpファイルはサーバ内に存在。   
4. 返却された値をブラウザが受け取り、.doneの処理を実行し、描画。
<img width="710" alt="スクリーンショット 2019-10-04 19.24.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299210/12520b03-c6dd-aa02-5a76-bc7580224752.png">

<img width="1440" alt="スクリーンショット 2019-10-04 19.27.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299210/6e1310d7-8c15-6de7-2deb-ace1338e95fc.png">

また、上図のようにコンソールに出力がある。これは、通信成功と失敗に関わらず以下の処理が実行されたためである。
<img width="706" alt="スクリーンショット 2019-10-04 19.48.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299210/85988503-6f52-6af9-243b-a0cfad409385.png">

上記の1~4の手順において、ページの切り替えが生じないこともAjaxの利便性としてよく挙げられる。
 
## 終わりに
浅学ながらフロント開発には欠かせないAjaxの基本について執筆させていただきました。
誤りがありましたらコメントにてご指摘いただけると幸いです。

## 参考文献
- [はじめてのAjax(jQuery) 2018年版 - Qiita](https://qiita.com/zakiyamaaaaa/items/bdda422db2ccbaea60d9)
- [Ajax入門（通信エラーとなった原因の取得） - Laravel学習帳](https://laraweb.net/surrounding/4991/)