【JavaScript】Ajax - HTTP通信の同期・非同期とGET・POST
JavaScriptのAjaxについて解説します。
検証環境
Ajax
Ajaxは『Asynchronous JavaScript + XML』の略称で“Http通信の仕組み”です。
同期処理・非同期処理に対応しており、サーバーとのデータ取得やデータ送信を行うために使用します。
同期・非同期
Http通信はサーバーにリクエストを送信し、結果をレスポンスとして受け取ります。
ネットワークを介した通信のため、一連の処理に多少の時間がかかります。
この一連の処理が完了するまでJavaScriptの処理を一時停止(待機)する方法を同期処理、完了を待たずに次の処理へ移行する方法を非同期処理と呼びます。
手順
Ajaxの基本的な手順は次のとおりです。
- 生成
- 初期化
- リクエスト送信
- レスポンス処理
この手順に沿って次の4つの基本的な通信を解説します。
- 同期: GET
- 同期: POST
- 非同期: GET
- 非同期: POST
同期(GET)
同期処理かつGETリクエストの方法をご紹介します。
生成
XMLHttpRequestのオブジェクトを生成します。
基本構文
new XMLHttpRequest()
サンプル
___ih_hl_start
let request = new XMLHttpRequest();
___ih_hl_end
初期化
Http通信の基本情報を初期化します。
基本構文
変数.open(メソッド, URL, 非同期可否);
サンプル
let request = new XMLHttpRequest();
___diff_start
+request.open('GET', 'https://it-hack.net/api/sample/js/ajax/get/data', false);
___diff_end
送信
Http通信のリクエストを送信します。
基本構文
変数.send()
サンプル
let request = new XMLHttpRequest();
request.open('GET', 'https://it-hack.net/api/sample/js/ajax/get/data', false);
___diff_start
+request.send();
___diff_end
レスポンス処理
Http通信のレスポンスを処理します。
レスポンスのステータスが正常な場合に、データを取り出します。
基本構文
if( request.status == レスポンスステータス ) {
// レスポンスデータの処理........
}
サンプル
let request = new XMLHttpRequest();
request.open('GET', 'https://it-hack.net/api/sample/js/ajax/get/data', false);
request.send();
___diff_start
+if( request.status == 200 ) {
+ console.log(request.response);
+}
___diff_end
{"A":"aaa","B":"bbb","C":"ccc"}
status
プロパティはレスポンスステータスです。
ステータスはコード(数値)で表わし、一般的には次の意味を持ちます。
コード | 意味 |
---|---|
200 | 正常 |
403 | 権限なし |
404 | Not Found |
500 | サーバーエラー |
※ リクエスト先のアプリケーションにより異なる場合があります。
サンプルでは正常(200
)の場合にresponse
プロパティからレスポンスデータを取得し出力しています。
同期(POST)
POSTリクエスはサーバーにデータを送信する際に使います。
基本は同期(GET)と同じですが、送信データタイプと送信データを設定します。
送信データタイプ
送信するデータのタイプを設定します。
代表的なタイプはHTMLフォームデータ(application/x-www-form-urlencoded
)やJSONデータ(application/json
)があります。
基本構文
変数.setRequestHeader("Content-Type", データタイプ);
サンプル
let request = new XMLHttpRequest();
request.open('POST', 'https://it-hack.net/api/sample/js/ajax/post/data', false);
___diff_start
+request.setRequestHeader("Content-Type", "application/json");
___diff_end
送信データ
リクエストを送信するsend
メソッドの引数にデータを渡します。
基本構文
変数.send(データ);
サンプル
let request = new XMLHttpRequest();
request.open('POST', 'https://it-hack.net/api/sample/js/ajax/post/data', false);
request.setRequestHeader("Content-Type", "application/json");
___diff_start
+request.send(JSON.stringify({ name: 'apple', price: '150' }));
___diff_end
if( request.status == 200 ) {
console.log(request.response);
}
{"name":"apple","price":"150","code":"XXXX"}
send
メソッドの引数は文字列です。
そのため、JSON.stringify
メソッドによりJSONデータ(オブジェクト)を文字列に変換しています。
このサンプルのリクエスト先は受け取ったJSONデータにcode
プロパティを追加してレスポンスを返しますが、コンソール結果から正常に動作したことが分かります。
非同期(GET)
非同期処理はリクエストの送信後、JavaScriptの実行を停止せずに次の処理へ進みます。
そのため、レスポンスを受け取ったタイミングでレスポンス処理を実行するコールバック関数(レスポンスを受け取ったときに実行する関数)を設定します。
具体的にはオブジェクトの状態を表すreadyState
プロパティとそのプロパティが更新されたタイミングで呼び出されるonreadystatechange
イベントハンドラにコールバック関数を設定し処理を制御します。
readyState
プロパティは数値でオブジェクトの状態を表わします。
数値 | 意味 |
---|---|
0 | 未初期化 |
1 | 初期化済み |
2 | レスポンス待機 |
3 | レスポンス受信中 |
4 | レスポンス受信完了 |
レスポンス受信完了を示す4
の時にレスポンス処理を行うようコールバック関数を定義します。
また、open
メソッドの第3引数をtrue
に設定します。
コールバック関数の設定
onreadystatechange
プロパティにコールバック関数を設定します。
基本構文
request.onreadystatechange = コールバック関数
サンプル
let request = new XMLHttpRequest();
___diff_start
+request.onreadystatechange = function() {
+ console.log(request.readyState);
+ if (request.readyState == 4) {
+ console.log(request.response);
+ }
+}
___diff_end
request.open('GET', 'https://it-hack.net/api/sample/js/ajax/get/data', true);
request.send();
1
2
3
4
{"A":"aaa","B":"bbb","C":"ccc"}
コンソール結果からreadyState
プロパティが4
の時にレスポンスデータを出力したことが分かります。
また、
非同期(POST)
非同期処理のPOSTリクエストは上記で解説した方法の組み合わせで実現できます。
let request = new XMLHttpRequest();
request.onreadystatechange = function() {
console.log(request.readyState);
if (request.readyState == 4) {
console.log(request.response);
}
}
request.open('POST', 'https://it-hack.net/api/sample/js/ajax/post/data', true);
request.setRequestHeader("Content-Type", "application/json");
request.send(JSON.stringify({ name: 'apple', price: '150' }));
1
2
3
4
{"name":"apple","price":"150","code":"XXXX"}
非同期(GET)をベースにPOSTリクエストに必要な処理を追加しました。
同期/非同期の比較
同期処理と非同期処理の違いをプログラムの動作で確認するため、send
メソッドのリクエスト送信後にコンソール出力処理を入れて比較します。
同期
let request = new XMLHttpRequest();
request.open('GET', 'https://it-hack.net/api/sample/js/ajax/get/data', false);
request.send();
if( request.status == 200 ) {
console.log(request.response);
}
console.log("FINISH");
{"A":"aaa","B":"bbb","C":"ccc"}
FINISH
同期処理はレスポンスの受信を待機します。
そのため、コードの順序に沿った実行結果になります。
非同期
let request = new XMLHttpRequest();
request.onreadystatechange = function() {
if (request.readyState == 4) {
console.log(request.response);
}
}
request.open('GET', 'https://it-hack.net/api/sample/js/ajax/get/data', true);
request.send();
console.log("FINISH");
FINISH
{"A":"aaa","B":"bbb","C":"ccc"}
非同期処理はレスポンスの受信を待たずに次の処理に進みます。
そのためHttp通信のタイムラグにより、先にconsole.log("FINISH")
が実行されます。