備忘録的プログラミングリファレンス

非同期通信 XMLHttpRequest

 非同期通信とは、非同期処理のひとつでweb ページの遷移がない状態でサーバーと通信を行いページ内の一部を変更することを可能にする手法です。ページのリロードを行わなくても一部を更新することができます。
 通信方法は web ページと同じ HTTP 接続で web サーバーと通信を行います。そのため、web サーバーに URL でリクエストします。

 非同期通信はチャット、ゲーム、メールなどの web アプリケーションに利用されています。

 JavaScript における非同期通信として Ajax ( Asynchronous JavaScript And XML )があります。
 これは決まった方法があるわけではなく、HTML、CSS、JavaScript を利用して非同期通信を行う手法を全般的に Ajax と呼んでいるようです。

 ここでは XMLHttpRequest オブジェクトを使用した方法を取り上げます。

非同期通信 ドキュメントの読み込み
// 非同期通信
function import_PartText( id_insert_element, url_fl ){
	// 非同期通信のためのインスタンスの生成
	const xhr_rel = new XMLHttpRequest();

	// 受信と処理
	xhr_rel.onreadystatechange = function() {
		if( xhr_rel.readyState === 4 && xhr_rel.status === 200) {
			document.getElementById( id_insert_element ).innerHTML = this.response.body.innerHTML;
		}
	}

	// 通信を開始
	xhr_rel.open('get', url_fl);
	xhr_rel.responseType = "document";
	xhr_rel.send();

	return( xhr_rel );
}

 上記の例のように XMLHttpRequest の利用方法には大きく分けて、インスタンス(オブジェクト)の生成、通信が始まったらその通信の確立されたかを捉えて任意の処理を行う部分と通信を開始する部分があります。

 XMLHttpRequest でのエラー処理はイベントを捉えてステータス番号で場合分けする方法を使用します。try ~ catch と XMLHttpRequest の併用は上手く機能しないようです。

 似た言葉に非同期処理があります。非同期処理はファイルの読み書きやネットワーク経由の読み書き、一定時間ごとの処理といったマルチに行われる処理のことです。非同期通信も非同期処理の1つです。

ページ内 Index

XMLHttpRequest について

 XMLHttpRequest の利用方法には大きく分けて、インスタンスの生成、通信が始まったらその通信の確立されたかを捉えて任意の処理を行う部分と通信を開始する部分があります。

XMLHttpRequest インスタンスの生成

 まず必要になるのが XMLHttpRequest インスタンスです。XMLHttpRequest() コンストラクターを利用します。

XMLHttpRequest オブジェクト
const xhr_rel = new XMLHttpRequest();

 インスタンスはオブジェクトとも呼ばれます。正確にはオブジェクトは概念で、インスタンスはその概念を具現化したものです。インスタンスはオブジェクトなのですが、完全にオブジェクトの概念に沿ってはいないためインスタンスと呼んでいます。

 このインスタンスには socket 通信やファイル操作に似たプロパティとメソッドをもちます。

ファイルオープンとリクエストの送信

 生成したインスタンスの open()、send() メソッドでによってファイルオープン、リクエストの送信を行います。

リクエストを送信
// 通信をファイルとしてオープンする
xhr_rel.open('get', url_fl);
// 受信するデータタイプを指定
xhr_rel.responseType = "document";
// リクエストをサーバーに送る
xhr_rel.send();

 作成された XMLHttpRequest インスタンスのプロパティやメソッドを利用して、サーバーと通信を行います。

 .open() メソッドで外部通信のファイルオープンを行います。ここでは通信手段を設定しています。リクエストは send() メソッドで行います。
 open() である理由は、外部への入出力である I/O とのやりとりもファイル操作として行うことから由来します。
 第1引数はデータの送信方法で、GET、POSTが代表的なものです。第2引数はサーバーの URL です。

 .responseType はサーバーからのレスポンスデータのタイプを予め指定するものです。ここではdocumentを指定しています。

 .send() はサーバーへリクエストを送信します。

レスポンスデータの処理

 send() メソッドでサーバーにリクエストを送ったら、サーバーからのデータを受け取れるように以下のような受信のためのブロックを編集しておきます。

受信と処理
xhr_rel.onreadystatechange = function() {
	if( xhr_rel.readyState === 4 && xhr_rel.status === 200) {
		document.getElementById( id_insert_element ).innerHTML = this.response.body.innerHTML;
	}
}

 読み込みに関するイベント onreadystatechange または onload で通信状態を捉えます。イベント定義にダンロード完了時などのコードを編集します。

 このブロックは、例非同期通信 ドキュメントの読み込みのように .send() メソッドの前に定義していおいた方がエラーを回避できることがあります。

ステータスコード

 .readyState や .status の状態を示す番号です。ここで通信が完了した場合のみを対象にしていますので、.readyState === 4、 .status === 200 を使用しています。

.readyState のステータスコード
コードエラー名概要
0UNSENTXMLHttpRequest インスタンスは生成済み。open() が実行されていない
1OPENEDopen() の実行完了
2HEADERS_RECEIVEDsend() の実行完了。ヘッダーとステータスは参照可能
3LOADINGダウンロード中
4DONEダウンロード完了

 .status は HTTP ステータスコードです。ここではダウンロードが問題なく完了した 200 ステータスコードを使用しています。 HTTP ステータスコードはより詳しいサイトを参考にしてください。

レスポンスデータタイプ

 XMLHttpRequest インスタンスで扱えるレスポンスデータにはテキストやバイナリーデータがあります。
 テキストには XML、JSON、HTML、String 型データがあります。バイナリーデータは画像などのコンピュータが直接に解析できるデータです。

 XMLHttpRequest インスタンスでレスポンスデータを以下のように指定します。

リクエストを送信
// 受信するデータタイプを指定
xhr_rel.responseType = "document";

 この .responseType で受け取るデータのタイプを指定します。データのタイプには以下があります。

データタイプ概要
""デフォルト。"text" と同じ
"arraybuffer"ArrayBuffer型
"blob"Blob オブジェクト
"document"Document または XMLDocument 。MIME タイプに基づく
"json"JSON 型
"text"DOMString オブジェクトのテキスト

 XML データは "document"、JSON デーは "json" です。バイナリーデータは "blob" です。
 指定がなければ "text" になり、String データとして扱われます。

Ajax について

 Ajax ( Asynchronous JavaScript And XML )は非同期通信としての手段全般を指します。
 これは決まった方法があるわけではなく、HTML、CSS、JavaScript を利用して非同期通信を行う手法を全般的に Ajax と呼んでいるようです。

 Ajax の概念としては web ページをアプリケーションにようにページの遷移なしでインタラクティブに扱えるようにしたものです。Ajax によるアプリケーションのような操作性をもつ web ページ、サイトを web アプリケーションと呼んでいるようです。

 現在は主に上記の XMLHttpRequest を利用する方法が使われています。

 Ajax も基本的には HTTP 通信を利用します。web サーバーにリクエストをして返ってきたデータを JavaScript などで処理します。

Node.js について

 非同期通信を調べると Node.js についてが出てきます。Node.js は非同期通信もできますが用途が違うようです。

 Node.js は JavaScript で書かれたプログラムのランタイム環境(実行環境)です。Node.js がインストールされた環境であれば、JavaScript から直接にOSとやりとりをすることができます 。
 ブラウザ環境では JavaScript コンピュータのディスクドライブや外部への I/O との通信ができません。しかし、Node.js がインストールされた環境ではブラウザ上では禁止されている機能が利用可能になります。

 Node.js をサーバーにインストールすると web サーバーとして利用することができます。
 さらに Socket.IO によって双方向通信が可能になります。通常の HTTP 通信ではブラウザからリクエストがない限りサーバーは何も答えません。しかし、Socket.IO によってサーバーからブラウザにレスポンスを送ることができるようになります。

 詳しくは Node.js で調べてみてください。