Ajaxの基本知識とサンプルスクリプト

非同期通信について色々サンプルスクリプトを書いたので
書き留めて置こうと思います。

#Ajaxとは？

Asynchronous JavaScript + XML の略で非同期なjavascriptとxmlです。
名前にXMLとありますがXMLを使用する必要はありません。
ポイントは非同期というところで、ブラウザのページをリロードすることなく
HTTPリクエストを送ることができます。
上手く使うことができればページリロードの分、UXを向上させることができるので使えるようになっておきたいところです。
なお現在では少し時代遅れの手法となっているようでFetchAPIを使うことが増えてきているようです。

#Javascriptで書く

まずはライブラリを使わずに生のjavascriptで書いていきます。

https://developer.mozilla.org/ja/docs/Web/API/XMLHttpRequest
ここのリファレンスを参考にしています。

```javascript:main.js
var xhr = new XMLHttpRequest();
xhr.open('GET', 'sample.php');
xhr.onload = function () {
  console.log(xhr.response);
};
xhr.send();
```

これが基本形です。これでsample.phpに対してGETリクエストが発行されます。

・XMLHttpRequestオブジェクトのインスタンス作成
・openメソッドでHTTPメソッドとURIを指定
・イベントの設定
・sendメソッドでリクエスト

がJavasciptで非同期通信を行うのに必要な要素です。

##ajaxイベントについて

addEventListenerでclickを指定することと同じ等に
httpリクエストの進捗状況をトリガーにしてイベントを設定することができます。
上記の例ではonload()を設定していますがこれは
「結果取得が完了」した時に発火するイベントです。

他には下記のようなイベントが用意されています。

| 値 | 状態 | 説明 |
|--:|:--|:--|
| 0 | UNSENT | クライアントは作成済み。open() はまだ呼ばれていない。 |
| 1 | OPENED | open() が呼び出し済み。 |
| 2 | HEADERS_RECEIVED | send() が呼び出し済みで、ヘッダーとステータスが利用可能。 |
| 3 | LOADING | ダウンロード中。responseText には部分データが入っている。 |
| 4 | DONE | 操作が完了した。 |
>詳しくは[MDN web docs](https://developer.mozilla.org/ja/docs/Web/API/XMLHttpRequest/readyState)をご覧ください


このreadyStateを利用してデータ取得中には「loading now....」という文字を
出すといった操作が可能になります。

##リクエストの結果はどこにある？

**XMLHttpRequestオブジェクトのresponseプロパティ**に入っています。
また、responseText、responseURLなど他のプロパティにも
HTTPリクエストの結果が入っています。

またJSON形式で受け取りたい場合はresponseプロパティを
JSON.parseする必要があります。


##パラメータをPOST(またはGET)したい場合は？

###GETリクエスト

openメソッドに渡すurlをパラメータ付きにして渡します。
例えば　sample.php?id=1　といったような形です。

###POSTリクエスト

POSTで渡す場合は
・headerにContent-Typeを指定する
・send()メソッドの引数にデータを渡す
必要があります。

```javascript
//ヘッダーの指定
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

//sendメソッドにdataを渡す
var data = "id=1";
xhr.send(data);
```
ヘッダーを指定しないとデータが受け取れないので注意です。
Content-Typeにはapplication/x-www-form-urlencodedを指定しておけば
htmlのフォームでPOST送信した際と同じヘッダになります。

##FormDataを使ってデータをまとめる

postするデータの形式は、'key=value&key=value'という形を
取らなければなりません。
このままでは動的にデータを作って行くときに非常に不便です。
そこでFormDataというオブジェクトを使用すれば
appendメソッドで簡単にデータの追加ができます。

```javascript:FormDataのサンプルコード
var data = new FormData();
data.append("id", 1);
data.append("name", "suzuki");

xhr.send(data);
```

またHTMLのフォームから取得したいのであれば次のように
省略して書くこともできます。

```javascript:HTMLフォームから取得
var form = document.querySelector('form');

xhr.send(new FormData(form));
```


FormDataオブジェクト、便利。

ただ注意点としてFormDataを使ってsendするときに
ヘッダーの指定は不要です。

##サンプルスクリプト

ここまでの内容を使ってシンプルなスクリプトを書いてみます。
フォームに入力した名前がphpへ送信されて返ってきたデータを取得するスクリプトです。


```html:indexhtml
<!DOCTYPE html>
<html>
<head>
  <title>Sample</title>
</head>
<body>
  <form>
    名前：<input type="text" name="name">
  </form>
  <button>送信</button>
  <div>表示エリア</div>
  <script scr="main.js"></script>
</body>
</html>
```

```javascript:main.js
'use strict';

{
  var button = document.querySelector('button');
  var result = document.querySelector('result');

  button.addEventListener('click', function() {
    var form = document.querySelector('form');
    var xhr = new XMLHttpRequest();
    xhr.open('POST', 'sapmle.php');
    xhr.onload = function() {
      result.textContent = xhr.response;
    };
    xhr.send(new FormData(form));
  });
}
```

```php:smaple.php
<?php

echo "ようこそ、" . $_POST["name"] . "さん";
```


ただただPOSTで送った値を使って文字列を返しているだけのスクリプトですが
javascriptでリクエストが送信できているのが確認できます。



##参考リンク
[ウェブデベロッパーガイド](https://developer.mozilla.org/ja/docs/Web/Guide)