非同期通信について色々サンプルスクリプトを書いたので
書き留めて置こうと思います。
#Ajaxとは?
Asynchronous JavaScript + XML の略で非同期なjavascriptとxmlです。
名前にXMLとありますがXMLを使用する必要はありません。
ポイントは非同期というところで、ブラウザのページをリロードすることなく
HTTPリクエストを送ることができます。
上手く使うことができればページリロードの分、UXを向上させることができるので使えるようになっておきたいところです。
なお現在では少し時代遅れの手法となっているようでFetchAPIを使うことが増えてきているようです。
#Javascriptで書く
まずはライブラリを使わずに生のjavascriptで書いていきます。
https://developer.mozilla.org/ja/docs/Web/API/XMLHttpRequest
ここのリファレンスを参考にしています。
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をご覧ください
この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()メソッドの引数にデータを渡す
必要があります。
//ヘッダーの指定
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メソッドで簡単にデータの追加ができます。
var data = new FormData();
data.append("id", 1);
data.append("name", "suzuki");
xhr.send(data);
またHTMLのフォームから取得したいのであれば次のように
省略して書くこともできます。
var form = document.querySelector('form');
xhr.send(new FormData(form));
FormDataオブジェクト、便利。
ただ注意点としてFormDataを使ってsendするときに
ヘッダーの指定は不要です。
##サンプルスクリプト
ここまでの内容を使ってシンプルなスクリプトを書いてみます。
フォームに入力した名前がphpへ送信されて返ってきたデータを取得するスクリプトです。
<!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>
'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
echo "ようこそ、" . $_POST["name"] . "さん";
ただただPOSTで送った値を使って文字列を返しているだけのスクリプトですが
javascriptでリクエストが送信できているのが確認できます。
##参考リンク
ウェブデベロッパーガイド