JavascriptのAjaxについての基本まとめ

## Ajaxとは
Asynchronous JavaScript + XMLの略。
すなわちJavascriptとXMLを使用して非同期（Asynchronous）でページ内容を更新する技術のこと。

①クライアントから非同期更新に必要なデータをサーバに送る
②サーバはデータを受け取ってクライアントに整形済データを返す
③クライアントはサーバから受け取った整形済データをDOMに反映する

ざっくりこのような流れでAjaxは実現されている。
クライアントからデータを送ったり、サーバから整形済データが返ってきたと検知するところにJavascriptのXTR（XMLHttpRequest）という技術が使われていて、返ってくる整形済データがXMLだったりするのでAsynchronous JavaScript + XMLと呼ばれている。
ただしXMLは名前だけ残っている感じで、今は返ってくるデータはJSONというフォーマットであることが多い。

## Ajaxを実装するためのステップ
### 素のJavascriptで実装する
AjaxはjQueryやaxiosなどのライブラリで実装することも多いが、まずは基本として素のjavascriptで実装してみる。
今回はサーバサイドスクリプトにphpを使用する。

クライアントで名前を入力してサーバに送信したら、サーバで名前に整形をし、それをクライアントに返すというのをやってみる。

```html:index.html
<form name="fm">
	<label>名前：<input type="text" name="name" size="15"></label>
	<input type="button" id="btnsend" name="submit" value="送信" onclick="asyncSend()">
</form>
<div id="result"></div><!-- このdiv内に整形したデータを非同期で入れる -->
```
```php:helloAjax.php
<?php
print('こんにちは、'.$_REQUEST['name'].'さん！');
```

上のようなhtmlで送信ボタンをクリックしたら応答メッセージをresultに非同期で表示する。
関数asyncSend内に次の処理を記述していく。

#### 1.XMLHttpRequestオブジェクトを生成する
```js:js
var req = new XMLHttpRequest();
```

#### 2.サーバ応答時の処理を定義する
XMLHttpRequestオブジェクトはreadyState/statusプロパティで通信の状態や応答ステータスを確認できる。
これらが変化したタイミングでコールバック関数を起動するようにする。
コールバック関数はonreadystatechangedプロパティで設定する。

```js:
req.onreadystatechange = function() {
  var result = document.getElementById('result');
  if (req.readyState == 4) { // 通信の完了時
    if (req.status == 200) { // 通信の成功時
      result.innerHTML = req.responseText;
    }
  }else{
    result.innerHTML = "通信中...";
  }
}
```
通信が完了する前は通信中...と表示し、通信の成功時にXMLHttpRequestオブジェクトの受け取ったプレーンテキストをhtml内に記述する。
statusが200でなかったらエラーメッセージなどもここで記述できる。

#### 3.サーバに要求データ（リクエスト）を送信する
リクエストを送信するには、まずopenメソッドでリクエストを初期化する。

```js:
req.open('GET', 'helloAjax.php?name=' + encodeURIComponent(document.fm.name.value), true);
req.send(null);
```

openメソッドは次のような書式
`XMLHttpRequestオブジェクト.open(HTTPメソッド, URL, 非同期モードで通信するか, ユーザー名, パスワード)`
ユーザー名とパスワードは認証が必要なページのみ指定。

- HTTPメソッドは数百バイト以内ならGET、それ以上大きいならPOST
- URLの末尾に`?キー名=値&`の形式で情報を追加
- 異なるドメインには送信できない。URLは相対パスで指定

最後にsendメソッドでリクエストを送信。
- openメソッドでPOSTにした場合は引数にリクエスト内容を指定
- openメソッドでGETにした場合はnull

##### POSTメソッドの場合
```js:
req.open('POST', 'helloAjax.php', true);
req.setRequestHeader('content-type',
  'application/x-www-form-urlencoded;charset=UTF-8');
req.send('name=' + encodeURIComponent(document.fm.name.value));
```
ContentTypeヘッダとしてapplication/x-www-form-urlencoded;charset=UTF-8を指定する。
またsendメソッドの引数にリクエスト内容を指定する。

#### レスポンスとしてjsonを受け取る場合
```js:
var data = eval('(' + req.responseText + ')');
```
サーバサイドjson化したデータをresponseTextメソッドで受け取り、eval関数でコードとして変数に格納する。
この変数からDOMを操作して表示する。

素のJavascriptだと以上のような感じでできるが、IEのバージョンごとに別の書き方をしたりするのでクロスブラウザ対応が必要だったり書き方が冗長なので面倒。
なので普通はjQueryやaxiosなどの専用ライブラリを使用する。

### jQueryで実装する
```js:
$('#btnsend').on('click', function(){
  $('#result').text('通信中...');
  // Ajax通信を開始
  $.ajax({
    url: 'helloAjax.php',
    type: 'GET',
    dataType: 'json',
    // フォーム要素の内容をハッシュ形式に変換
    data: $('form').serializeArray(),
    timeout: 5000,
  })
  .done(function(data) {
      // 通信成功時の処理を記述
  })
  .fail(function() {
	  // 通信失敗時の処理を記述
  });
})
```

$.ajaxメソッドにより、ステータスの状態で分岐してコールバック関数を記述するのではなく、オブジェクトリテラル形式で指定できるようになる。
また、クロスブラウザ問題も気にする必要がない。

### Ajax関連の便利なメソッド
- $.get：HTTP GET通信
- $.post：HTTP POST通信
- $.getJSON：JSONデータの取得
- $.getScript：スクリプトの取得

細かなオプションは指定できないが、それぞれの目的に特化してシンプルに実装できる。