第3章 応用・JavaScript関連技術

Ajax(Asynchronous JavaScript and XML)の利用方法

Ajaxとは

Ajax(Asynchronous JavaScript and XML)はサーバと通信を行うための技術です。ユーザのリクエストに応じて、ページを遷移することなくサーバにあるJSONファイルや、データベースの情報を取得し、表示させることができます。
Ajaxは通常、非同期通信と呼ばれる方式でサーバと通信します。非同期通信とは、サーバからレスポンスが返ってくるのを待つことなく、他の処理に進めることができます。この間、ユーザは任意の作業を続けることができます。その反対の同期通信は、レスポンスが返ってくるまで他の処理をすることができません。リクエストのたびに操作ができなくなるため、ユーザビリティは低くなります。

Ajaxを使った通信

JavaScriptでAjaxを実現するには、XMLHttpRequestを使います。このXMLHttpRequestを使ってGithubというサービスのAPIに接続し、データを受け取ってみましょう。

CodePen: https://codepen.io/zionboogie/pen/rdVBRa
JavaScript
// XMLHttpRequestのインスタンスを作成
var req = new XMLHttpRequest();

// 接続先のURLやメソッドを設定します
req.open( "GET", "https://api.github.com/users/zionboogie/repos" );

// リクエストをサーバに送信
req.send();
 
// 読み込み時の処理を設定
req.onreadystatechange = function() {
	// readyState=4は全てのデータを受信済み、
	// status=200は正常に処理されたことを意味します
	if( req.readyState == 4 && req.status == 200 ) {
		// responseTextに格納された情報を出力
		alert( req.responseText );
	}
}

HTMLを作成するか、CodePenなどのサービスを使ってテストしてみてください。CodePenの場合は用意されたConsoleだとデータ量が多くて表示されませんが、ブラウザのコンソールを使ってレスポンスの内容を確認できます。
Ajaxでのサーバとの通信は、まずXMLHttpRequestのインスタンスを作成することから始まります。作成したインスタンスから、XMLHttpRequestのメソッドやプロパティにアクセスします。

var req = new XMLHttpRequest();

インスタンス作成後、open()メソッドを使って接続先のURLなどの接続方法を設定します。

req.open( "GET", "https://api.github.com/users/zionboogie/repos" );

open()の引数は、第1引数がHTTPメソッドの指定、第2引数が接続するURL、第3引数が非同期通信を行うかどうかの論理値です(デフォルトが非同期)。HTTPメソッドは、サーバにデータを送信、受信する際の方式です。主なものにGETPOSTがあります。GETはURLを使って通信する方式で、扱うのが文字列なため、POSTと比べると簡単に扱うことができます。その反面、文字数に制限があったり、バイナリが扱えないといった制限があります。POSTはソケットを使って通信する方式で、GETと比べると複雑ですが、GETにあるような制限はありません。
send()メソッドはリクエストを送信するメソッドです。引数にリクエストボディーの文字列を指定できます

// リクエストをサーバに送信
req.send();

GETの場合、リクエストパラメータを引数に指定できます。

req.send( "name1=v1&name2=v2" );

GithubのレスポンスはJSONフォーマットのテキスト情報で、responseTextプロパティで取得できます。

alert( req.responseText );

JSONを扱えるライブラリはjQuery以外にも色々ありますが、ここではjQueryのgetJSON()を使いました。getJSON()はJSONを取得し、ドット記法で簡単に参照できるようにしてくれます。

$( ".box" ).append( data.id + " " + data.name );

getJSON()の構文は下記の通りです。

構文:
jQuery.getJSON( url [,オブジェクト] [,コールバック関数( 受信データ, ステータス, jqXHR )] )
引数
引数 説明
url リクエストの送信先URLを設定します。
オブジェクト サーバに送信したいデータがある場合、オブジェクト型の変数を指定できます。
コールバック関数 コールバック関数を指定します。引数には受信データ、ステータス、jqXHRを指定できます。
[MEMO]:HTTP(Hypertext Transfer Protocol)

ブラウザとWebサーバは、HTTPを通じてメッセージの交換を行います。HTTPは、HTMLやテキストファイル、画像などのリソースをクライアントに送信するための規格です。メッセージにリソースに特殊文字、日本語なおdの複数バイトの文字コードが含まれている場合は、URLエンコードしてから送信されます。

エラー処理

リクエストは必ず成功するわけではなく、リクエスト内容に不備があった場合などにエラーを返します。レスポンスには、リクエストを受け付けたかどうか、終了したかどうかなどの状態を知らせるreadyState、リクエストが正常に処理されたか、エラーだったかを伝えるstatusプロパティなどが含まれます。
readyStateの値が変わるたびに自動的に呼び出されるonreadystatechangeを使って、レスポンスが返って来たかどうかを判別します。onreadystatechangeはコールバック関数を指定するためのプロパティです。

CodePen: https://codepen.io/zionboogie/pen/oqXvKW
JavaScript
// 読み込み時の処理を設定
req.onreadystatechange = function() {
	try {
		// readyStateの4は全てのデータを受信済みを意味します
		if ( req.readyState == 4 ) {
			// statusの200は正常に処理されたことを意味します
			if ( req.status == 200 ) {
				console.log( JSON.parse( req.responseText ) );
			} else {
				console.error( "正常に処理されませんでした。" );
			}
		}
	} catch( e ) {
		console.error( "例外: " + e.description );
	}
}

readyStateはリクエストが終了すると4を返し、statusは正常に処理された場合は200を返します。readyState、statusがともに成功したら、データを取得しましょう。受信したデータはresponseTextから取得できます。

[MEMO]:サンドボックス

サンドボックスとは、実行できる領域が制限されており、ウイルスなどが外部に及ばないようにするための仕組みです。XMLHttpRequestはサンドボックス(セキュリティ)が適用されているので、同じドメインにあるデータのみが取得可能です。別ドメインや、ローカルにあるデータは取得できないので注意してください。
「子供を遊ばせるのは砂場(サンドボックス)のみ」という意味からこの名称が使われました。
今のモダンブラウザはXMLHttpRequest Level2が実装されており、別ドメイン間でも通信が可能になりました。ただし、リクエストを受ける側のサーバでクロスドメインでのアクセスを許可する設定が必要です。

[MEMO]:Internet Exploler対応

Internet Explolerの10以前はXMLHttpRequestに対応しておらず、代わりにActiveXObjectが使われていました。ただし、このActiveXObjectもバージョンごとに違いがあるため、さらにIEのバージョンごとの対応が必要になります。どうしても古いIEにも対応が必要な場合は条件分岐で対応できはしますが、jQueryなどのライブラリなどを使うことを検討したほうが良いかもしれません。

関連記事