JavaScript プログラミング講座

 

XMLHttpRequest とは?

 


■Ajax について

 
JavaScript を利用すると、「非同期なデータの送受信」を行なう事ができます。
 
また、JavaScript は「HTML の内容を動的に変更」する事もできます。
 
「非同期通信」と「ダイナミックHTML」の2つの技術を組み合わせたものを Ajax といいます。
 
Asynchronous JavaScript + XML)
 
Ajax を利用すると、「非同期通信」を行い外部から最新のデータを取得しながら、「ダイナミックHTML」で HTML の内容をリアルタイムに更新する事ができます。
 
ページを再読込する事無く、最新の情報をインタラクティブに供給する事ができます。
 
このページでは、「非同期通信」の方法について解説しています。
 
「ダイナミックHTML」については、「ドキュメントオブジェクトモデル(DOM)について」で解説しています。
 

■XMLHttpRequest とは?

 
 
XMLHttpRequest (XHR) は、非同期なデータの通信を実現するための API です。
 
元々は、「Internet Explorer 5」 で「ActiveX オブジェクト」として実装されましたが、他のブラウザでも互換性のある同等の機能が実装されはじめ、 XMLHttpRequest として利用できるようになりました。
 
Internet Explorer 7 以降の場合、XMLHttpRequest 側の API が利用できます。
 


 

基本的な使い方について

 
 


■XMLHttpRequest オブジェクトを作成する

 
new 演算子を使って、XMLHttpRequest オブジェクトを作成します。
 
XMLHttpRequest オブジェクトを作成する

// XMLHttpRequest オブジェクトを作成
var xhr = new XMLHttpRequest();

// 出力テスト
console.log(xhr);
 
■Internet Explorer 6 以前の場合
 
Internet Explorer 6 以前では、「ActiveX オブジェクト」を利用する必要があります。
 
XMLHttpRequest オブジェクトを作成する関数です。
 
XMLHttpRequest オブジェクトを作成する関数

// ------------------------------------------------------------
// XMLHttpRequest オブジェクトを作成する関数
// ------------------------------------------------------------
function XMLHttpRequestCreate(){

	// ------------------------------------------------------------
	// XMLHttpRequest オブジェクトを作成
	// ------------------------------------------------------------
	try{
		return new XMLHttpRequest();
	}catch(e){}

	// ------------------------------------------------------------
	// Internet Explorer 6 用
	// ------------------------------------------------------------
	try{
		return new ActiveXObject('MSXML2.XMLHTTP.6.0');
	}catch(e){}
	try{
		return new ActiveXObject('MSXML2.XMLHTTP.3.0');
	}catch(e){}
	try{
		return new ActiveXObject('MSXML2.XMLHTTP');
	}catch(e){}

	// ------------------------------------------------------------
	// 未対応
	// ------------------------------------------------------------
	return null;
}
 

■Internet Explorer 6 以前との互換性について

 
ActiveX オブジェクト版は、以下の機能に対応しています。(一部抜粋)
 
これらの機能のみを利用すると、Internet Explorer 6 以前でも動作するようになります。
 
■利用可能なプロパティ
 
プロパティ 説明
readyState Number XHR 通信の状態を取得する
status Number HTTP ステータスを取得する
statusText String HTTP ステータスをテキストで取得する
responseText String レスポンスボディの内容を String 型で取得する
responseXML Document レスポンスボディの内容を Document 型で取得する
 
■利用可能なメソッド
 
メソッド 説明
open() 「HTTP メソッド」を指定する、「アクセス先 URL」を指定する
send() 「送信データ」を指定する、「XHR 通信」を開始する
abort() 「XHR 通信」を中止する
setRequestHeader() リクエストヘッダを設定する
getResponseHeader() レスポンスヘッダの情報を1つ取得する
getAllResponseHeaders() レスポンスヘッダの情報をまとめて取得する
 
■利用可能なイベント
 
プロパティ 説明
onreadystatechange なし XHR 通信の状態が変化するたびに実行される
 
■イベントハンドラ内の this に注意
 
イベントハンドラ内で、this 演算子を使用する場合、注意が必要です。
 
参照場所が異なるため、互換性が失われます。
 

■互換性を考慮したシンプルな使用例

 
互換性を考慮した、シンプルな XMLHttpRequest の使用例です。
 
Internet Explorer 6 以前でも動作します。
 
互換性を考慮したシンプルな XMLHttpRequest の使用例

// ------------------------------------------------------------
// XMLHttpRequest オブジェクトを作成する関数
// ------------------------------------------------------------
function XMLHttpRequestCreate(){
	try{
		return new XMLHttpRequest();
	}catch(e){}
	try{
		return new ActiveXObject('MSXML2.XMLHTTP.6.0');
	}catch(e){}
	try{
		return new ActiveXObject('MSXML2.XMLHTTP.3.0');
	}catch(e){}
	try{
		return new ActiveXObject('MSXML2.XMLHTTP');
	}catch(e){}

	return null;
}

// ------------------------------------------------------------
// XMLHttpRequest オブジェクトを作成
// ------------------------------------------------------------
var xhr = XMLHttpRequestCreate();

// ------------------------------------------------------------
// XHR 通信の状態が変化するたびに実行されるイベント
// ------------------------------------------------------------
xhr.onreadystatechange = function (){

	switch(xhr.readyState){
	case 4:
		// ------------------------------------------------------------
		// XHR 通信失敗
		// ------------------------------------------------------------
		if(xhr.status == 0){

			alert("XHR 通信失敗");

		// ------------------------------------------------------------
		// XHR 通信成功
		// ------------------------------------------------------------
		}else{

			// ------------------------------------------------------------
			// リクエスト成功
			// ------------------------------------------------------------
			if((200 <= xhr.status && xhr.status < 300) || (xhr.status == 304)){

				alert("受信:" + xhr.responseText);

			// ------------------------------------------------------------
			// リクエスト失敗
			// ------------------------------------------------------------
			}else{

				alert("その他の応答:" + xhr.status);

			}
		}
		break;
	}
};

// ------------------------------------------------------------
// 「POST メソッド」「接続先 URL」を指定
// ------------------------------------------------------------
var url = "http://example.com/test.cgi";
xhr.open("POST" , url);

// ------------------------------------------------------------
// 「送信データ」を指定、XHR 通信を開始する
// ------------------------------------------------------------
var send_data = "送信テスト";
xhr.send(send_data);
 


 

XMLHttpRequest の機能一覧

 


■ XMLHttpRequest クラスの機能一覧

 
■利用可能なプロパティ
 
プロパティ 説明 L
readyState Number XHR 通信の状態を取得する 1
status Number HTTP ステータスを取得する 1
statusText String HTTP ステータスをテキストで取得する 1
responseText String レスポンスボディの内容を String 型で取得する 1
responseXML Document レスポンスボディの内容を Document 型で取得する 1
responseType String レスポンスボディのデータ型を指定する 2
response * レスポンスボディの内容を任意のデータ型で取得する 2
upload XMLHttpRequestUpload XMLHttpRequestUpload オブジェクトを取得する 2
timeout Number タイムアウトエラーが発生するまでの時間を設定する 2
withCredentials Boolean Cookie などの認証情報を送信するか? 2
 
プロパティ 説明
responseURL String 最終的なリダイレクト先 URL アドレスを取得する(WHATWG 仕様)
 
■利用可能なメソッド
 
メソッド 説明L
open() 「HTTP メソッド」を指定する、「アクセス先 URL」を指定する 1
overrideMimeType() 「MIME Type」のオーバーライドを設定する 2
send() 「送信データ」を指定する、「XHR 通信」を開始する 1
abort() 「XHR 通信」を中止する 1
setRequestHeader() リクエストヘッダを設定する 1
getResponseHeader() レスポンスヘッダの情報を1つ取得する 1
getAllResponseHeaders() レスポンスヘッダの情報をまとめて取得する 1
 
■利用可能なイベント
 
プロパティ 説明L
onreadystatechange Event XHR 通信の状態が変化するたびに実行される 1
onloadstart ProgressEvent XHR 通信を開始したときに実行される 2
onprogress ProgressEvent 受信中に繰り返し実行される 2
onloadend ProgressEvent XHR 通信が完了したときに実行される(成功失敗に関係無く) 2
onload ProgressEvent XHR 送信が成功したときに実行される(成功時のみ) 2
onerror ProgressEvent XHR 送信が失敗したときに実行される(失敗時のみ) 2
onabort ProgressEvent XHR 通信を中止すると実行される 2
ontimeout ProgressEvent タイムアウトエラー発生時に実行される 2
 


 

JavaScript 側のデータ送信処理について

 
 


■「HTTP メソッド」と「アクセス先 URL」を指定する

 
アクセス先 URL を設定するには、open() メソッドを使用します。
 
このメソッドを呼び出した段階では、まだ通信は行われません。
 
XMLHttpRequest.open(HTTPメソッド , アクセス先のURL , 非同期実行か? , ユーザー名 , パスワード) :Void
第01引数 StringHTTP メソッドを指定する。"GET"、"POST"、"HEAD"、"PUT"、"DELETE"、"OPTIONS" など
第02引数 Stringアクセス先 の URL を指定する。
第03引数(略可)Boolean非同期実行なら ture、同期実行なら false を指定する。デフォルトは true
第04引数(略可)Stringユーザー名を指定する。
第05引数(略可)Stringパスワードを指定する。
戻り値 Voidなし
 
■第01引数 HTTP メソッドを指定する
 
HTTP メソッドについては、こちらで解説しています。
 
"GET" や "POST" や "HEAD" などを指定します。
 
■第02引数 「アクセス先 URL」と「クエリパラメータ」を指定

アクセス先の URL を文字列で指定します。
 
Blob URL Scheme を指定する事もできます。
 
第01引数で、"GET" や "HEAD" を指定した場合、送信データは URL に埋め込む必要があります。
 
クエリ文字列の記述方法については、こちらで解説しています。
 
■第03引数 非同期実行であるか

true を指定すると、非同期実行となります。デフォルトの動作です。
 
XHR 通信中でもプログラムが動き続けるので、必ずイベントから実行結果を得る必要があります。
 
false を指定すると、同期実行となります。
 
XHR 通信が完了するまで JavaScript の制御が返りません。
 
同期実行は使用しない方がいいでしょう。
 
XHR 通信が完了するまでの間、ブラウザが応答不能の状態に陥るからです。
 
■第04~05引数 ユーザー名とパスワード

認証が必要な場合、第04引数にユーザー名、第05引数にパスワードを指定します。
 
第04~05引数を省略した状態で、アクセス先で認証が必要だった場合、その場で認証入力用のダイアログボックスが表示されます。
 
■同一生成元ポリシー (Same-Origin Policy) について
 
プロトコルドメインポート番号」の3つを合わせたものを、オリジンといいます。
 
「現在の URL」と「アクセス先の URL」の、生成元(オリジン)が一致していない場合、XHR 通信は失敗します。
 
 
送受信処理は、実際に行われています。
 
受信結果が得られないだけであり、リクエストの送信は可能です。
 
ブラウザの拡張機能など、クロスサイト通信が可能な実行環境もあります。
 
■クロスサイト通信を行うには?
 
ブラウザが、CORS に対応している場合、アクセス制限を解除する事もできます。
 
クロスオリジンリソースシェアリングについては、こちらで解説しています。
 
■使用例
 
「GET メソッド」「接続先:"http://example.com/test.cgi"」を指定する

// ------------------------------------------------------------
// XMLHttpRequest オブジェクトを作成
// ------------------------------------------------------------
var xhr = new XMLHttpRequest();

// ------------------------------------------------------------
// 「GET メソッド」「接続先 URL」を指定
// ------------------------------------------------------------
var url = "http://example.com/test.cgi";
xhr.open("GET" , url);
 
「GET メソッド」「接続先:"http://example.com/test.cgi"」「非同期実行」「ユーザー名:"myname"」「パスワード:"mypassword"」を指定する

// ------------------------------------------------------------
// XMLHttpRequest オブジェクトを作成
// ------------------------------------------------------------
var xhr = new XMLHttpRequest();

// ------------------------------------------------------------
// 「POST メソッド」「接続先 URL」「非同期実行」「ユーザー名」「パスワード」を指定
// ------------------------------------------------------------
var url = "http://example.com/test.cgi";
xhr.open("POST" , url , true , "myname" , "mypassword");
 

■HTTP メソッドについて

 
■GET メソッド
 
GET メソッドは、送信データを、URL 文字列に埋め込んで送信します。
 
クエリ文字列の記述方法については、こちらで解説しています。
 
ユーザーが URL 文字列を見れば、送信した内容を容易に推測できます
 
送信できるサイズに限界があるので、パラメータの総量が少ない時に利用します。
 
■POST メソッド
 
POST メソッドは、送信データを、リクエストボディ内に格納して送信します。
 
大容量のデータを送る事ができるので、フォームの送信や、ファイルのアップロードに最適です。
 
■HEAD メソッド
 
HEAD メソッドは、レスポンスヘッダのみ取得を試みます
 
レスポンスボディは、受信結果に含まれません。
 
コンテンツタイプなどのヘッダ情報だけを調べたい場合に便利です。
 
クエリパラメータの送信方法は、GET メソッドと同じです。
 

■クエリ文字列について( URL 文字列に送信データを埋め込む)

 
まず、URL の最後に「?」を追加します。
 
もし「#」が含まれる場合、「#」の直前に挿入します。
 
次に、「名前=値」という書式で、データを追加します。
 
複数のデータを追加する場合、「&」で区切ります。
 
「接続先:"http://sub.example.com/test.cgi"」に送信情報を埋め込む例

http://sub.example.com/test.cgi?user=taro&age=18&blood=b
http://sub.example.com/test.cgi?user=hanako&age=16&blood=o#FRAGMENT_IDENTIFIER
 

■リクエストヘッダを設定する

 
リクエストヘッダを設定するには、setRequestHeader() メソッドを使用します。
 
XMLHttpRequest.setRequestHeader("ヘッダの種類","値") :Void
第01引数 Stringヘッダの種類を文字列で指定
第02引数 String値を文字列で指定
戻り値 Voidなし
 
■リクエストヘッダの一例
 
セキュリティの都合上、設定できない項目もあります。
 
ヘッダフィールドの種類 変更可 説明
Content-Type 送信データのコンテンツタイプ
Referer × 送信元の URL アドレス情報
User-Agent × ブラウザやOSなどのユーザーエージェント情報
 

■コンテンツタイプの一例

 
送信データのフォーマットを指定する事ができます。
 
指定しなかった場合、自動的に最適なコンテンツタイプが設定されます。
 
文字列 説明
text/plain テキスト文書
text/html HTML 文書
application/xml XML 文書
application/json JSON 文書
application/x-www-form-urlencoded 『変数名=値&変数名=値&変数名=値&変数名=値』の形式
例えば「user=taro」「age=18」「blood=b」という3つのパラメータを送信したい場合
『user=taro&age=18&blood=b』
 
■使用例
 
送信データのコンテンツタイプを指定する

// ------------------------------------------------------------
// XMLHttpRequest オブジェクトを作成する関数
// ------------------------------------------------------------
function XMLHttpRequestCreate(){
	try{
		return new XMLHttpRequest();
	}catch(e){}
	try{
		return new ActiveXObject('MSXML2.XMLHTTP.6.0');
	}catch(e){}
	try{
		return new ActiveXObject('MSXML2.XMLHTTP.3.0');
	}catch(e){}
	try{
		return new ActiveXObject('MSXML2.XMLHTTP');
	}catch(e){}

	return null;
}

// ------------------------------------------------------------
// XMLHttpRequest オブジェクトを作成
// ------------------------------------------------------------
var xhr = XMLHttpRequestCreate();

// ------------------------------------------------------------
// 「POST メソッド」「接続先 URL」を指定
// ------------------------------------------------------------
xhr.open("POST" , "http://example.com/test.cgi");

// ------------------------------------------------------------
// 送信データの「コンテンツタイプ」を指定
// ------------------------------------------------------------
xhr.setRequestHeader("Content-Type" , "text/plain");

// ------------------------------------------------------------
// 「送信データ」を指定、XHR 通信を開始する
// ------------------------------------------------------------
xhr.send("Hello World !!");
 

■「送信したいデータ」を指定し、XHR 通信を開始する

 
「送信したいデータ」を指定し、XHR 通信を開始するには、send() メソッドを使用します。
 
XMLHttpRequest.send( 送信データ ) :Void
第01引数(略可)*送信データを指定します。特にない場合は null を指定します。
戻り値 Voidなし
 
■第01引数 送信データ
 
第01引数に、送信データを指定します。
 
"GET" や "HEAD" メソッドを選択した場合は、ここで送信データを指定しても無意味です。
 
open() メソッドの第02引数から、クエリパラメータを埋め込む必要があります。
 
■送信可能なフォーマット
 
最も互換性のある、送信可能なデータ型は、文字列です。
 
文字列は、Internet Explorer 6 以前でも対応しています。
 
説明 Level
String 文字列データ 1
FormData フォームデータ(複数のファイルを含める事も可能) 2
ArrayBufferView バイナリデータ 2
Blob Blob や File オブジェクト(1つのファイル) 2
Document HTML や XML 文書 2
 
■同期実行について
 
同期実行を選択した場合、XHR 通信が終わるまで、send() メソッドから制御が返りません。
 
同期実行を指定するには、open() メソッドを使用します。
 
■ブラウザを使って通信内容を確認する
 
ブラウザの開発者向けツールを使用すると、通信内容を確認する事ができます。
 
使用方法は、こちらで解説しています。
 
■「GET メソッド」を使って「テキスト」を送信する例
 
「GET メソッド」を使って「テキスト」を送信する

// ------------------------------------------------------------
// XMLHttpRequest オブジェクトを作成する関数
// ------------------------------------------------------------
function XMLHttpRequestCreate(){
	try{
		return new XMLHttpRequest();
	}catch(e){}
	try{
		return new ActiveXObject('MSXML2.XMLHTTP.6.0');
	}catch(e){}
	try{
		return new ActiveXObject('MSXML2.XMLHTTP.3.0');
	}catch(e){}
	try{
		return new ActiveXObject('MSXML2.XMLHTTP');
	}catch(e){}

	return null;
}

// ------------------------------------------------------------
// 送信情報
// ------------------------------------------------------------
// 送信したい文字列
var send_data = "Hello World !!";

// アクセス先 URL
var url = "http://example.com/test.cgi";

// ------------------------------------------------------------
// XMLHttpRequest オブジェクトを作成
// ------------------------------------------------------------
var xhr = XMLHttpRequestCreate();

// ------------------------------------------------------------
// 「GET メソッド」「接続先 URL」を指定(送信したいデータを URL に含める)
// ------------------------------------------------------------
xhr.open("GET" , url + "?" + encodeURIComponent(send_data));

// ------------------------------------------------------------
// XHR 通信を開始する
// ------------------------------------------------------------
xhr.send(null);
 
■「POST メソッド」を使って「テキスト」を送信する例
 
「POST メソッド」を使って「テキスト」を送信する

// ------------------------------------------------------------
// XMLHttpRequest オブジェクトを作成する関数
// ------------------------------------------------------------
function XMLHttpRequestCreate(){
	try{
		return new XMLHttpRequest();
	}catch(e){}
	try{
		return new ActiveXObject('MSXML2.XMLHTTP.6.0');
	}catch(e){}
	try{
		return new ActiveXObject('MSXML2.XMLHTTP.3.0');
	}catch(e){}
	try{
		return new ActiveXObject('MSXML2.XMLHTTP');
	}catch(e){}

	return null;
}

// ------------------------------------------------------------
// 送信情報
// ------------------------------------------------------------
// 送信したい文字列
var send_data = "Hello World !!";

// アクセス先 URL
var url = "http://example.com/test.cgi";

// ------------------------------------------------------------
// XMLHttpRequest オブジェクトを作成
// ------------------------------------------------------------
var xhr = XMLHttpRequestCreate();

// ------------------------------------------------------------
// 「POST メソッド」「接続先 URL」を指定
// ------------------------------------------------------------
xhr.open("POST" , url);

// ------------------------------------------------------------
// 「送信データ」を指定、XHR 通信を開始する
// ------------------------------------------------------------
xhr.send(send_data);
 
■「POST メソッド」を使って「フォームデータ」を送信する例
 
「POST メソッド」を使って「フォームデータ」を送信する(HTML5 世代)

// 匿名関数を即時実行
(function(){

	// ------------------------------------------------------------
	// FormData に対応していない
	// ------------------------------------------------------------
	if(!(window.FormData)) return;

	// ------------------------------------------------------------
	// FormData オブジェクトを作成する
	// ------------------------------------------------------------
	var form_data = new FormData();

	// ------------------------------------------------------------
	// 名前と値を指定してデータを追加する
	// ------------------------------------------------------------
	form_data.append("aaa" , "value_a");
	form_data.append("bbb" , "value_b");
	form_data.append("ccc" , "value_c");

	// ------------------------------------------------------------
	// XMLHttpRequest オブジェクトを作成
	// ------------------------------------------------------------
	var xhr = new XMLHttpRequest();

	// ------------------------------------------------------------
	// 「POST メソッド」「接続先 URL」を指定
	// ------------------------------------------------------------
	xhr.open("POST" , "http://example.com/cgi-bin/upload.cgi");

	// ------------------------------------------------------------
	// 送信データに FormData を指定、XHR 通信を開始する
	// ------------------------------------------------------------
	xhr.send(form_data);
})();
 

■ XHR 通信を中止する

 
XHR 通信を中止するには、abort() メソッドを使用します。
 
ブラウザの読み込み停止ボタンを押したときと同じ動作です。
 
■関連するイベントについて
 
中止した場合、以下のイベントが発行されます。
 
onload と onerror イベントは、発行されないので注意して下さい。
 
プロパティ 説明L
onreadystatechange Event XHR 通信の状態が変化するたびに実行される 1
onloadend ProgressEvent XHR 通信が完了したときに実行される(成功失敗に関係無く) 2
onabort ProgressEvent XHR 通信を中止すると実行される 2
 
■使用例
 
XHR 通信を中止する

// ------------------------------------------------------------
// XMLHttpRequest オブジェクトを作成する関数
// ------------------------------------------------------------
function XMLHttpRequestCreate(){
	try{
		return new XMLHttpRequest();
	}catch(e){}
	try{
		return new ActiveXObject('MSXML2.XMLHTTP.6.0');
	}catch(e){}
	try{
		return new ActiveXObject('MSXML2.XMLHTTP.3.0');
	}catch(e){}
	try{
		return new ActiveXObject('MSXML2.XMLHTTP');
	}catch(e){}

	return null;
}

// ------------------------------------------------------------
// XMLHttpRequest オブジェクトを作成
// ------------------------------------------------------------
var xhr = XMLHttpRequestCreate();

// ------------------------------------------------------------
// XHR 通信の状態が変化するたびに実行されるイベント
// ------------------------------------------------------------
xhr.onreadystatechange = function(){
	if(xhr.readyState == 4){
		console.log("STATUS:" + xhr.status);
	}
};

// ------------------------------------------------------------
// 「POST メソッド」「接続先 URL」を指定
// ------------------------------------------------------------
xhr.open("POST" , "http://example.com/test.cgi");

// ------------------------------------------------------------
// 「送信データ」を指定、XHR 通信を開始する
// ------------------------------------------------------------
xhr.send("Hello World !!");

// ------------------------------------------------------------
// XHR 通信を中止する
// ------------------------------------------------------------
xhr.abort();
 
XHR 通信を中止する(HTML5 世代)

// ------------------------------------------------------------
// XMLHttpRequest オブジェクトを作成
// ------------------------------------------------------------
var xhr = new XMLHttpRequest();

// ------------------------------------------------------------
// XHR 通信を中止すると実行されるイベント
// ------------------------------------------------------------
xhr.onabort = function(e){
	console.log("XHR 通信中止");
};

// ------------------------------------------------------------
// 「POST メソッド」「接続先 URL」を指定
// ------------------------------------------------------------
xhr.open("POST" , "http://example.com/test.cgi");

// ------------------------------------------------------------
// 「送信データ」を指定、XHR 通信を開始する
// ------------------------------------------------------------
xhr.send("Hello World !!");

// ------------------------------------------------------------
// XHR 通信を中止する
// ------------------------------------------------------------
xhr.abort();
 

■タイムアウトを設定する(HTML5 世代)

 
タイムアウトエラーが発生するまでの時間を設定するには、timeout プロパティを使用します。
 
指定する単位はミリ秒です。初期値は 0 です。
 
■設定タイミングについて
 
open() メソッドから send() メソッドまでの間に設定します。
 
■関連するイベントについて
 
タイムアウトエラーが発生した場合、以下のイベントが発行されます。
 
onload と onerror イベントは、発行されないので注意して下さい。
 
プロパティ 説明L
onreadystatechange Event XHR 通信の状態が変化するたびに実行される 1
onloadend ProgressEvent XHR 通信が完了したときに実行される(成功失敗に関係無く) 2
ontimeout ProgressEvent タイムアウトエラー発生時に実行される 2
 
■使用例
 
タイムアウトを設定する(HTML5 世代)

// ------------------------------------------------------------
// XMLHttpRequest オブジェクトを作成
// ------------------------------------------------------------
var xhr = new XMLHttpRequest();

// ------------------------------------------------------------
// 「GET メソッド」「接続先 URL」を指定
// ------------------------------------------------------------
xhr.open("GET" , "http://example.com/test.cgi");

// ------------------------------------------------------------
// タイムアウト機能をサポートしているか
// ------------------------------------------------------------
if(xhr.timeout !== undefined){

	// ------------------------------------------------------------
	// タイムアウトエラー発生時に実行されるイベント
	// ------------------------------------------------------------
	xhr.ontimeout = function(e){
		console.log("タイムアウトエラー発生");
	};

	// ------------------------------------------------------------
	// タイムアウトエラーが発生するまでの時間(ミリ秒)を設定
	// ------------------------------------------------------------
	xhr.timeout = 2000;

}

// ------------------------------------------------------------
// XHR 通信を開始する
// ------------------------------------------------------------
xhr.send(null);
 

■「MIME Type」のオーバーライドを設定する(HTML5 世代)

 
「MIME Type」のオーバーライドを設定するには、overrideMimeType() メソッドを使用します。
 
「MIME Type」の上書きは、クライアント側で作用します。
 
通常の手順で得られた受信データを、クライアント側で1度だけデータ変換します。
 
XMLHttpRequest.overrideMimeType( "MIME Type" ) :Void
第01引数 String上書きしたい MIME Type を指定。
戻り値 Voidなし。
 
■設定タイミングについて
 
send() メソッドを実行する前に、設定を済ませる必要があります。
 
■ UTF-8 以外の文書を読み込む
 
UTF-8 以外の文書を読み込むと、基本的に文字化けします
 
レスポンスヘッダの「Content-Type」に「charset」情報が含まれない場合、UTF-8 文書であると解釈されるからです。
 
文字コードが自動的に類推される事はありません。
 
そこで、「MIME Type」を上書きして、「charset」情報を付加します。
 
例えば、Shift-JIS 文書を読み込むには、「text/plain; charset=Shift_JIS」を指定します。
 
Shift-JIS 文書を読み込む(HTML5 世代)

// ------------------------------------------------------------
// Blob オブジェクトを作成(Shift-JIS 形式のプレーンテキスト)
// ------------------------------------------------------------
var blob = new Blob([new Uint8Array([ 0x82,0xa0 , 0x82,0xa2 , 0x82,0xa4 ])] , {type:"text/plain"});

// Blob URL Scheme を生成する
var blob_url = window.URL.createObjectURL(blob);

// ------------------------------------------------------------
// XMLHttpRequest オブジェクトを作成
// ------------------------------------------------------------
var xhr = new XMLHttpRequest();

// ------------------------------------------------------------
// XHR 送信が成功したときに実行されるイベント
// ------------------------------------------------------------
xhr.onload = function(e){
	// 出力テスト
	console.log(xhr.responseText); // "あいう"
};

// ------------------------------------------------------------
// 「GET メソッド」「Blob URL」を指定
// ------------------------------------------------------------
xhr.open("GET" , blob_url);

// ------------------------------------------------------------
// overrideMimeType メソッドをサポートしている
// ------------------------------------------------------------
if(xhr.overrideMimeType){

	// ------------------------------------------------------------
	// 「MIME Type」のオーバーライドを設定する
	// ------------------------------------------------------------
	xhr.overrideMimeType("text/plain; charset=Shift_JIS");

}

// ------------------------------------------------------------
// XHR 通信を開始する
// ------------------------------------------------------------
xhr.send(null);
 
■ XML テキストのパースを試みる
 
レスポンスヘッダの「Content-Type」が XML 文書ではない場合、Document オブジェクトへの変換処理は動作しません。
 
そこで、「application/xml」を指定します。
 
正確な XML テキストであれば、Document オブジェクトへ変換する事ができます。
 
DOMParser クラスを使って、XML 文字列をパースする事もできます。
 
XML テキストを読み込む(HTML5 世代)

// ------------------------------------------------------------
// Blob オブジェクトを作成( XML が書かれたプレーンテキスト)
// ------------------------------------------------------------
var blob = new Blob(['<xml><element attribute="value">text</element></xml>'] , {type:"text/plain"});

// Blob URL Scheme を生成する
var blob_url = window.URL.createObjectURL(blob);

// ------------------------------------------------------------
// XMLHttpRequest オブジェクトを作成
// ------------------------------------------------------------
var xhr = new XMLHttpRequest();

// ------------------------------------------------------------
// XHR 送信が成功したときに実行されるイベント
// ------------------------------------------------------------
xhr.onload = function(e){
	// 出力テスト
	console.log(xhr.responseXML);
};

// ------------------------------------------------------------
// 「GET メソッド」「Blob URL」を指定
// ------------------------------------------------------------
xhr.open("GET" , blob_url);

// ------------------------------------------------------------
// overrideMimeType メソッドをサポートしている
// ------------------------------------------------------------
if(xhr.overrideMimeType){

	// ------------------------------------------------------------
	// 「MIME Type」のオーバーライドを設定する
	// ------------------------------------------------------------
	xhr.overrideMimeType("application/xml");

}

// ------------------------------------------------------------
// XHR 通信を開始する
// ------------------------------------------------------------
xhr.send(null);
 
■バイナリを入手する
 
「text/plain; charset=x-user-defined」を指定すると、「x-user-defined 文字列」を取得することができます。
 
「x-user-defined 文字列」については、こちらで解説しています。
 
resourceType プロパティの方を優先的に利用した方が、多くの環境で動作します。
 
バイナリ形式で読み込む(HTML5 世代)

// ------------------------------------------------------------
// Blob オブジェクトを作成(バイナリ)
// ------------------------------------------------------------
var blob = new Blob([new Uint8Array([ 0xe3,0x81,0x82,0xe3,0x81,0x84,0xe3,0x81,0x86 ])] , {type:"application/octet-stream"});

// Blob URL Scheme を生成する
var blob_url = window.URL.createObjectURL(blob);

// ------------------------------------------------------------
// XMLHttpRequest オブジェクトを作成
// ------------------------------------------------------------
var xhr = new XMLHttpRequest();

// ------------------------------------------------------------
// XHR 送信が成功したときに実行されるイベント
// ------------------------------------------------------------
xhr.onload = function(e){

	var x_user_defined = xhr.responseText;

	// 総サイズを取得
	var size = x_user_defined.length;

	// Uint8Array オブジェクトを作成
	var ary_u8 = new Uint8Array(size);

	// 下位1バイトを順番にコピー
	var i;
	for(i=0;i < size;i++){
		ary_u8[i] = x_user_defined.charCodeAt(i) & 0xFF;
	}

	// 出力テスト
	console.log(ary_u8); // [0xe3,0x81,0x82,0xe3,0x81,0x84,0xe3,0x81,0x86]
};

// ------------------------------------------------------------
// 「GET メソッド」「Blob URL」を指定
// ------------------------------------------------------------
xhr.open("GET" , blob_url);

// ------------------------------------------------------------
// overrideMimeType メソッドをサポートしている
// ------------------------------------------------------------
if(xhr.overrideMimeType){

	// ------------------------------------------------------------
	// 「MIME Type」のオーバーライドを設定する
	// ------------------------------------------------------------
	xhr.overrideMimeType("text/plain; charset=x-user-defined");

}

// ------------------------------------------------------------
// XHR 通信を開始する
// ------------------------------------------------------------
xhr.send(null);
 

■ファイルをアップロードする(HTML5 世代)

 
ファイルのアップロードについては、こちらで解説しています。
 

■送信中の進捗状況を調べる(HTML5 世代)

 
■XMLHttpRequestUpload オブジェクトを取得する
 
XMLHttpRequestUpload オブジェクトを取得するには、upload プロパティを使用します。
 
XMLHttpRequestUpload オブジェクトを取得する(HTML5 世代)

// ------------------------------------------------------------
// XMLHttpRequest オブジェクトを作成
// ------------------------------------------------------------
var xhr = new XMLHttpRequest();

// ------------------------------------------------------------
// XMLHttpRequestUpload オブジェクトを取得
// ------------------------------------------------------------
var upload = xhr.upload;

// 出力テスト
console.log(upload);
 
■POST メソッドを使用する
 
送信時にイベントを発行させるには、POST メソッドを使用する必要があります。
 
■送信の進捗イベントについて
 
失敗に関係なく、必ず送信の完了を知るには、onloadend イベントを使用します。
 
イベント 説明 L
onloadstart ProgressEvent 送信を開始したときに実行される 2
onprogress ProgressEvent 送信中に繰り返し実行される 2
onloadend ProgressEvent 送信が完了したときに実行される(成功失敗に関係無く) 2
 
■送信の結果イベントについて
 
以下の4つのイベントは、同時に発行されることはありません。
 
よって1つでも欠けている場合、送信の完了を取りこぼします。
 
イベント 説明 L
onload ProgressEvent 送信が成功したときに実行される(成功時のみ) 2
onerror ProgressEvent 送信が失敗したときに実行される(失敗時のみ) 2
onabort ProgressEvent 送信中に XHR 通信を中止すると実行される 2
ontimeout ProgressEvent 送信中にタイムアウトエラーが発生すると実行される 2
 
■ProgressEvent オブジェクトについて
 
登録したコールバック関数の引数から、ProgressEvent オブジェクトが得られます。
 
ProgressEvent オブジェクトには、以下のプロパティがあります。
 
プロパティ名説明
lengthComputableBoolean進捗のサイズ計算が可能であるかを取得
loadedNumberこれまでに完了した送信バイト数を取得
totalNumber全体の送信バイト数を取得
 
■送信結果を取得する例
 
送信結果を取得する(HTML5 世代)

// ------------------------------------------------------------
// 1 Mbyte 相当の Uint8Array オブジェクトを作成
// ------------------------------------------------------------
var ary_u8 = new Uint8Array(1024 * 1024 * 1);

// ------------------------------------------------------------
// XMLHttpRequest オブジェクトを作成
// ------------------------------------------------------------
var xhr = new XMLHttpRequest();

// ------------------------------------------------------------
// XMLHttpRequestUpload オブジェクトを取得
// ------------------------------------------------------------
var upload = xhr.upload;
if(upload){

	// ------------------------------------------------------------
	// 送信が成功したときに実行されるイベント
	// ------------------------------------------------------------
	upload.onload = function(e){
		console.log("送信に成功");
	};

	// ------------------------------------------------------------
	// 送信が失敗したときに実行されるイベント
	// ------------------------------------------------------------
	upload.onerror = function(e){
		console.log("送信に失敗");
	};

	// ------------------------------------------------------------
	// 送信中に XHR 通信を中止すると実行されるイベント
	// ------------------------------------------------------------
	upload.onabort = function(e){
		console.log("XHR 通信を中止");
	};

	// ------------------------------------------------------------
	// 送信中にタイムアウトエラーが発生すると実行されるイベント
	// ------------------------------------------------------------
	upload.ontimeout = function(e){
		console.log("タイムアウトエラーが発生");
	};

}

// ------------------------------------------------------------
// 「POST メソッド」「接続先 URL」を指定
// ------------------------------------------------------------
xhr.open("POST" , "http://example.com/upload.cgi");

// ------------------------------------------------------------
// 「送信データ」を指定、XHR 通信を開始する
// ------------------------------------------------------------
xhr.send(ary_u8);
 
■送信中の進捗状況を取得する例
 
送信中の進捗状況を取得する(HTML5 世代)

// ------------------------------------------------------------
// 10 Mbyte 相当の Uint8Array オブジェクトを作成
// ------------------------------------------------------------
var ary_u8 = new Uint8Array(1024 * 1024 * 10);

// ------------------------------------------------------------
// XMLHttpRequest オブジェクトを作成
// ------------------------------------------------------------
var xhr = new XMLHttpRequest();

// ------------------------------------------------------------
// XMLHttpRequestUpload オブジェクトを取得
// ------------------------------------------------------------
var upload = xhr.upload;
if(upload){

	// ------------------------------------------------------------
	// 送信を開始したときに実行されるイベント
	// ------------------------------------------------------------
	upload.onloadstart = function(e){
		console.log("送信を開始");
	};

	// ------------------------------------------------------------
	// 送信中に繰り返し実行されるイベント
	// ------------------------------------------------------------
	upload.onprogress = function(e){
		console.log("送信中: " + e.loaded + " / " + e.total);
	};

	// ------------------------------------------------------------
	// 送信が完了したときに実行されるイベント
	// ------------------------------------------------------------
	upload.onloadend = function(e){
		console.log("送信が完了");
	};
}

// ------------------------------------------------------------
// 「POST メソッド」「接続先 URL」を指定
// ------------------------------------------------------------
xhr.open("POST" , "http://example.com/upload.cgi");

// ------------------------------------------------------------
// 「送信データ」を指定、XHR 通信を開始する
// ------------------------------------------------------------
xhr.send(ary_u8);
 
■アップロード用のプログレスバーを表示する例
 
アップロード用のプログレスバーを表示する(HTML5 世代)

<html>
  <body>

    <form id="my_form" action="http://example.com/cgi-bin/upload.cgi" method="post" enctype="multipart/form-data" >

      <input type="file" name="input_file0"> <br>
      <input type="file" name="input_file1"> <br>

      <input type="submit" value="送信">

    </form>

    <div id="my_result" style="width:300px; text-align:right; margin-bottom:5px;"> --- </div>

    <div style="width:300px; height:10px; background:#fff; border:2px solid #000; line-height:0;">
	    <div id="my_progress" style="width:0px; height:10px; background:#ccc;"></div>
    </div>

    <script type="text/javascript">
    <!--
	// 匿名関数を即時実行
	(function(){

		// ------------------------------------------------------------
		// サポートチェック
		// ------------------------------------------------------------
		// イベントリスナーに対応していない
		if(!(window.addEventListener)) return;
		// FormData に対応していない
		if(!(window.FormData)) return;

		// ------------------------------------------------------------
		// エレメントに文字列をセットして、テキストノードを構築する関数
		// ------------------------------------------------------------
		function ElementSetTextContent(element,str){
			if(element.textContent !== undefined){
				element.textContent = str;
			}
			if(element.innerText !== undefined){
				element.innerText = str;
			}
		}

		// ------------------------------------------------------------
		// 各エレメントを取得
		// ------------------------------------------------------------
		// id 属性が "my_form" であるエレメントを取得
		var form = document.getElementById("my_form");

		// id 属性が "my_result" であるエレメントを取得
		var result = document.getElementById("my_result");

		// id 属性が "my_progress" であるエレメントを取得
		var progress = document.getElementById("my_progress");

		// ------------------------------------------------------------
		// サブミット直前に実行されるイベント
		// ------------------------------------------------------------
		form.addEventListener("submit" , function(e){

			// ------------------------------------------------------------
			// フォームの送信処理を中止
			// ------------------------------------------------------------
			e.preventDefault();

			// ------------------------------------------------------------
			// FormData オブジェクトを作成
			// ------------------------------------------------------------
			var form_data = new FormData(form);

			// ------------------------------------------------------------
			// XMLHttpRequest オブジェクトを作成
			// ------------------------------------------------------------
			var xhr = new XMLHttpRequest();

			// ------------------------------------------------------------
			// XMLHttpRequestUpload オブジェクトを取得
			// ------------------------------------------------------------
			var upload = xhr.upload;

			// ------------------------------------------------------------
			// 送信中に繰り返し実行されるイベント
			// ------------------------------------------------------------
			upload.onprogress = function(e){

				// リザルトを更新
				ElementSetTextContent(result,e.loaded + " / " + e.total + " Byte");

				// プログレスバーを更新
				if(e.lengthComputable){
					var percent = (e.loaded / e.total * 100);
					progress.style.width = (percent) + "%";
				}
			};

			// ------------------------------------------------------------
			// 「POST メソッド」「接続先 URL」を指定(フォームの action 属性の値を使用)
			// ------------------------------------------------------------
			xhr.open("POST" , form.action);

			// ------------------------------------------------------------
			// 送信データに FormData を指定、XHR 通信を開始する
			// ------------------------------------------------------------
			xhr.send(form_data);
		});
	})();

    //-->
    </script>

  </body>
</html>
 


 

JavaScript 側のデータ送信処理について

 
 
 


■XHR 通信の状態を調べる

 
■readyState プロパティについて
 
XHR 通信の状態を取得するには、readyState プロパティを使用します。
 
以下の値が得られます。
 
定数 解説
0 UNSENT XMLHttpRequest オブジェクトを作成した直後である。
1 OPENED open() メソッドの呼び出しが完了した。
2 HEADERS_RECEIVED レスポンスヘッダの受信が完了した。
3 LOADING レスポンスボディを受信中である。(繰り返し実行される)
4 DONE XHR 通信が完了した。(成功失敗に関わらず)
 
■ onreadystatechange イベントについて
 
XHR 通信の状態が変化したか調べるには、onreadystatechange イベントを使用します。
 
send() メソッドを実行する前に、リスナーの登録を済ませる必要があります。
 
このイベントに登録した関数内で、readyState プロパティを調べます。
 
ダウンロードの進捗状況の取得については、こちらで解説しています。
 
■取得例
 
XHR 通信の状態を取得する

// ------------------------------------------------------------
// XMLHttpRequest オブジェクトを作成する関数
// ------------------------------------------------------------
function XMLHttpRequestCreate(){
	try{
		return new XMLHttpRequest();
	}catch(e){}
	try{
		return new ActiveXObject('MSXML2.XMLHTTP.6.0');
	}catch(e){}
	try{
		return new ActiveXObject('MSXML2.XMLHTTP.3.0');
	}catch(e){}
	try{
		return new ActiveXObject('MSXML2.XMLHTTP');
	}catch(e){}

	return null;
}

// ------------------------------------------------------------
// XMLHttpRequest オブジェクトを作成
// ------------------------------------------------------------
var xhr = XMLHttpRequestCreate();

// ------------------------------------------------------------
// XHR 通信の状態が変化するたびに実行されるイベント
// ------------------------------------------------------------
xhr.onreadystatechange = function (){

	switch(xhr.readyState){
	case 1:
		console.log("open() メソッドの呼び出しが完了した");
		break;

	case 2:
		console.log("レスポンスヘッダの受信が完了した");
		break;

	case 3:
		console.log("レスポンスボディを受信中(繰り返し実行される)");
		break;

	case 4:
		console.log("XHR 通信が完了した(成功失敗に関わらず)");
		break;
	};
};

// ------------------------------------------------------------
// 「GET メソッド」「接続先 URL」を指定
// ------------------------------------------------------------
xhr.open("GET" , "http://example.com/test.cgi");

// ------------------------------------------------------------
// XHR 通信を開始する
// ------------------------------------------------------------
xhr.send(null);
 

■ XHR 通信が完了したか調べる

 
■ XHR 通信が完了したか調べる(成功失敗に関係無く)
 
XHR 通信が完了したか調べるには、readyState が、4 (DONE) であるか調べます。
 
onreadystatechange イベントを使って監視します。
 
XHR 通信の状態を調べる方法については、こちらで解説しています。
 
■ status プロパティについて
 
HTTP ステータスコードを取得するには、status プロパティを使用します。
 
readyState が、2 (HEADERS_RECEIVED) 以上であれば、アクセスできます。
 
通信結果が確定するのは、4 (DONE) のときです。
 
status プロパティから 0 が得られた場合、XHR 通信の失敗を意味します。
 
■ statusText プロパティについて
 
HTTP ステータスの意味を文字列で取得するには、statusText プロパティを使用します。
 
readyState が、2 (HEADERS_RECEIVED) 以上であれば、アクセスできます。
 
通信結果が確定するのは、4 (DONE) のときです。
 
■ XHR 通信の結果を調べる
 
status プロパティが 0 である場合、XHR 通信は失敗しています。
 
status プロパティが 0 以外である場合、XHR 通信は成功しています。
 
XHR 通信に成功しているからといって、リクエストが成功しているとは限りません。
 
サーバーからエラーコードが得られる場合があります。 (404、500、503 など)
 
■サーバへのリクエストが成功したか調べる
 
status プロパティが 200 である場合、リクエストに成功しています。
 
他には、2xx304 なども、リクエストの成功を意味します。
 
■使用例
 
XHR 通信が完了したか調べる

// ------------------------------------------------------------
// XMLHttpRequest オブジェクトを作成する関数
// ------------------------------------------------------------
function XMLHttpRequestCreate(){
	try{
		return new XMLHttpRequest();
	}catch(e){}
	try{
		return new ActiveXObject('MSXML2.XMLHTTP.6.0');
	}catch(e){}
	try{
		return new ActiveXObject('MSXML2.XMLHTTP.3.0');
	}catch(e){}
	try{
		return new ActiveXObject('MSXML2.XMLHTTP');
	}catch(e){}

	return null;
}

// ------------------------------------------------------------
// XMLHttpRequest オブジェクトを作成
// ------------------------------------------------------------
var xhr = XMLHttpRequestCreate();

// ------------------------------------------------------------
// XHR 通信の状態が変化するたびに実行されるイベント
// ------------------------------------------------------------
xhr.onreadystatechange = function (){

	switch(xhr.readyState){
	case 4:
		// ------------------------------------------------------------
		// XHR 通信失敗
		// ------------------------------------------------------------
		if(xhr.status == 0){

			console.log("XHR 通信失敗");

		// ------------------------------------------------------------
		// XHR 通信成功
		// ------------------------------------------------------------
		}else{

			console.log("XHR 通信成功");
			console.log("ステータスコード:" + xhr.status);
			console.log("ステータス:" + xhr.statusText);

			// ------------------------------------------------------------
			// リクエスト成功
			// ------------------------------------------------------------
			if((200 <= xhr.status && xhr.status < 300) || (xhr.status == 304)){

				console.log("リクエスト成功");

			// ------------------------------------------------------------
			// リクエスト失敗
			// ------------------------------------------------------------
			}else{

				console.log("リクエスト失敗");

			}
		}
		break;
	}
};

// ------------------------------------------------------------
// 「GET メソッド」「接続先 URL」を指定
// ------------------------------------------------------------
xhr.open("GET" , "http://example.com/test.cgi");

// ------------------------------------------------------------
// XHR 通信を開始する
// ------------------------------------------------------------
xhr.send(null);
 

■受信したレスポンスヘッダを取得する

 
■レスポンスヘッダの一例
 
ヘッダの種類 説明
Content-Type 受信データのコンテンツタイプ
Content-Length 受信データのバイトサイズ
Last-Modified 最終更新日
 
■レスポンスヘッダの情報を1つ取得する
 
レスポンスヘッダの情報を1つ取得するには、getResponseHeader() メソッドを使用します。
 
readyState が、2 (HEADERS_RECEIVED) 以上であれば、アクセスできます。
 
XMLHttpRequest.getResponseHeader( "ヘッダの種類" ) :String
第01引数 String取得したいヘッダの種類を、文字列で指定。
戻り値 String指定したヘッダの情報が文字列で得られる。存在しない場合は、空文字 "" か null。
 
レスポンスヘッダの情報を1つずつ取得する

// ------------------------------------------------------------
// XMLHttpRequest オブジェクトを作成する関数
// ------------------------------------------------------------
function XMLHttpRequestCreate(){
	try{
		return new XMLHttpRequest();
	}catch(e){}
	try{
		return new ActiveXObject('MSXML2.XMLHTTP.6.0');
	}catch(e){}
	try{
		return new ActiveXObject('MSXML2.XMLHTTP.3.0');
	}catch(e){}
	try{
		return new ActiveXObject('MSXML2.XMLHTTP');
	}catch(e){}

	return null;
}

// ------------------------------------------------------------
// XMLHttpRequest オブジェクトを作成
// ------------------------------------------------------------
var xhr = XMLHttpRequestCreate();

// ------------------------------------------------------------
// XHR 通信の状態が変化するたびに実行されるイベント
// ------------------------------------------------------------
xhr.onreadystatechange = function (){

	// ------------------------------------------------------------
	// レスポンスヘッダの受信が完了した
	// ------------------------------------------------------------
	if(xhr.readyState == 2){

		// ------------------------------------------------------------
		// レスポンスヘッダの情報を1つずつ取得
		// ------------------------------------------------------------
		// コンテンツタイプを取得
		var content_type   = xhr.getResponseHeader("Content-Type");

		// コンテンツのデータサイズを取得
		var content_length = xhr.getResponseHeader("Content-Length");

		// 最終更新日を取得
		var last_modified  = xhr.getResponseHeader("Last-Modified");

		// ------------------------------------------------------------
		// 出力テスト
		// ------------------------------------------------------------
		console.log("Content-Type: "   + content_type);
		console.log("Content-Length: " + content_length);
		console.log("Last-Modified: "  + last_modified);

	}
};

// ------------------------------------------------------------
// 「GET メソッド」「接続先 URL」を指定
// ------------------------------------------------------------
xhr.open("GET" , "http://example.com/test.cgi");

// ------------------------------------------------------------
// XHR 通信を開始する
// ------------------------------------------------------------
xhr.send(null);
 
■レスポンスヘッダの情報をまとめて取得する
 
レスポンスヘッダの情報をまとめて取得するには、getAllResponseHeaders() メソッドを使用します。
 
readyState が、2 (HEADERS_RECEIVED) 以上であれば、アクセスできます。
 
得られる文字列は、『名前: 値』というフォーマットです。
 
複数の情報が存在する場合、改行で区切られています。
 
XMLHttpRequest.getAllResponseHeaders( ) :String
第01引数 Voidなし
戻り値 Stringレスポンスヘッダ情報がまとめて文字列で得られる。存在しない場合は、空文字 "" か null。
 
レスポンスヘッダを取得し、オブジェクト型に変換する

// ------------------------------------------------------------
// XMLHttpRequest オブジェクトを作成する関数
// ------------------------------------------------------------
function XMLHttpRequestCreate(){
	try{
		return new XMLHttpRequest();
	}catch(e){}
	try{
		return new ActiveXObject('MSXML2.XMLHTTP.6.0');
	}catch(e){}
	try{
		return new ActiveXObject('MSXML2.XMLHTTP.3.0');
	}catch(e){}
	try{
		return new ActiveXObject('MSXML2.XMLHTTP');
	}catch(e){}

	return null;
}

// ------------------------------------------------------------
// レスポンスヘッダ文字列からオブジェクトに変換する関数
// ------------------------------------------------------------
function ResponseHeadersParseObject(str){
	var o = new Object();
	if(!str) return o;

	var a = str.replace(/\r\n?/g,"\n").split("\n");
	var m;
	var i;
	var num = a.length;
	for(i=0;i < num;i++){
		m = a[i].match(new RegExp("^(.*?):[ ](.*)$","i"));
		if(m){
			o[m[1]] = m[2];
		}
	}
	return o;
}

// ------------------------------------------------------------
// XMLHttpRequest オブジェクトを作成
// ------------------------------------------------------------
var xhr = XMLHttpRequestCreate();

// ------------------------------------------------------------
// XHR 通信の状態が変化するたびに実行されるイベント
// ------------------------------------------------------------
xhr.onreadystatechange = function (){

	// ------------------------------------------------------------
	// レスポンスヘッダの受信が完了した
	// ------------------------------------------------------------
	if(xhr.readyState == 2){

		// ------------------------------------------------------------
		// レスポンスヘッダ文字列からオブジェクトに変換
		// ------------------------------------------------------------
		var response_headers = ResponseHeadersParseObject(xhr.getAllResponseHeaders());

		// ------------------------------------------------------------
		// レスポンスヘッダの情報を1つずつ取得
		// ------------------------------------------------------------
		// コンテンツタイプを取得
		var content_type   = response_headers["Content-Type"];

		// コンテンツのデータサイズを取得
		var content_length = response_headers["Content-Length"];

		// 最終更新日を取得
		var last_modified  = response_headers["Last-Modified"];

		// ------------------------------------------------------------
		// 出力テスト
		// ------------------------------------------------------------
		console.log("Content-Type: "   + content_type);
		console.log("Content-Length: " + content_length);
		console.log("Last-Modified: "  + last_modified);

	}
};

// ------------------------------------------------------------
// 「GET メソッド」「接続先 URL」を指定
// ------------------------------------------------------------
xhr.open("GET" , "http://example.com/test.cgi");

// ------------------------------------------------------------
// XHR 通信を開始する
// ------------------------------------------------------------
xhr.send(null);
 

■受信したレスポンスボディを、String 型で取得する

 
■responseText プロパティについて
 
受信したレスポンスボディを、String 型で取得するには、responseText プロパティを使用します。
 
■取得可能なタイミングについて
 
readyState が、3 (LOADING) の場合、XHR 通信は受信中です。
 
これまでに完了した、部分的な受信結果を得る事ができます。
 
readyState が、4 (DONE) の場合、XHR 通信は完了しています。
 
すべての受信結果を得る事ができます。
 
■UTF-8 以外のテキストを読み込む(HTML5 世代)
 
「MIME Type」のオーバーライドについては、こちらで解説しています。
 
■取得例
 
受信したレスポンスボディを、String 型で取得する

// ------------------------------------------------------------
// XMLHttpRequest オブジェクトを作成する関数
// ------------------------------------------------------------
function XMLHttpRequestCreate(){
	try{
		return new XMLHttpRequest();
	}catch(e){}
	try{
		return new ActiveXObject('MSXML2.XMLHTTP.6.0');
	}catch(e){}
	try{
		return new ActiveXObject('MSXML2.XMLHTTP.3.0');
	}catch(e){}
	try{
		return new ActiveXObject('MSXML2.XMLHTTP');
	}catch(e){}

	return null;
}

// ------------------------------------------------------------
// XMLHttpRequest オブジェクトを作成
// ------------------------------------------------------------
var xhr = XMLHttpRequestCreate();

// ------------------------------------------------------------
// XHR 通信の状態が変化するたびに実行されるイベント
// ------------------------------------------------------------
xhr.onreadystatechange = function (){

	switch(xhr.readyState){

	// ------------------------------------------------------------
	// レスポンスボディを受信中(繰り返し実行される)
	// ------------------------------------------------------------
	case 3:
		console.log("受信中 :" + xhr.responseText.length + " characters");
		break;

	// ------------------------------------------------------------
	// XHR 通信が完了した(成功失敗に関わらず)
	// ------------------------------------------------------------
	case 4:

		// ------------------------------------------------------------
		// リクエスト成功
		// ------------------------------------------------------------
		if((200 <= xhr.status && xhr.status < 300) || (xhr.status == 304)){

			console.log("レスポンス:" + xhr.responseText);

		// ------------------------------------------------------------
		// リクエスト失敗
		// ------------------------------------------------------------
		}else{
			console.log("リクエスト失敗");

		}
		break;
	}
};

// ------------------------------------------------------------
// 「GET メソッド」「接続先 URL」を指定
// ------------------------------------------------------------
xhr.open("GET" , "http://example.com/test.cgi");

// ------------------------------------------------------------
// XHR 通信を開始する
// ------------------------------------------------------------
xhr.send(null);
 

■受信したレスポンスボディを、Document 型で取得する

 
■responseXML プロパティについて
 
受信したレスポンスボディを、Document 型で取得するには、responseXML プロパティを使用します。
 
XML 文書を読み込んで、Document オブジェクトを取得したい場合に使用します。
 
HTML 文書を読み込む事はできません。
 
XML パースに失敗した場合、null 値が得られます。
 
■responseXML プロパティの注意点
 
読み込む XML 文書は、フォーマットが正確である必要があります。
 
閉じタグが無いなどの不備がある場合、パースは失敗します。
 
DOMParser クラスを使って、XML 文字列をパースする事もできます。
 
■取得可能なタイミングについて
 
XHR 通信が完了している場合、responseXML プロパティにアクセス可能です。
 
XHR 通信が完了したか調べる方法については、こちらで解説しています。
 
■プレーンテキストから XML パースを試みる(HTML5 世代)
 
「MIME Type」のオーバーライドについては、こちらで解説しています。
 
■取得例
 
受信したレスポンスボディを、Document 型で取得する

// ------------------------------------------------------------
// XMLHttpRequest オブジェクトを作成する関数
// ------------------------------------------------------------
function XMLHttpRequestCreate(){
	try{
		return new XMLHttpRequest();
	}catch(e){}
	try{
		return new ActiveXObject('MSXML2.XMLHTTP.6.0');
	}catch(e){}
	try{
		return new ActiveXObject('MSXML2.XMLHTTP.3.0');
	}catch(e){}
	try{
		return new ActiveXObject('MSXML2.XMLHTTP');
	}catch(e){}

	return null;
}

// ------------------------------------------------------------
// XMLHttpRequest オブジェクトを作成
// ------------------------------------------------------------
var xhr = XMLHttpRequestCreate();

// ------------------------------------------------------------
// XHR 通信の状態が変化するたびに実行されるイベント
// ------------------------------------------------------------
xhr.onreadystatechange = function (){

	switch(xhr.readyState){

	// ------------------------------------------------------------
	// レスポンスボディを受信中(繰り返し実行される)
	// ------------------------------------------------------------
	case 3:
		console.log("受信中 :" + xhr.responseText.length + " characters");
		break;

	// ------------------------------------------------------------
	// XHR 通信が完了した(成功失敗に関わらず)
	// ------------------------------------------------------------
	case 4:

		// ------------------------------------------------------------
		// リクエスト成功
		// ------------------------------------------------------------
		if((200 <= xhr.status && xhr.status < 300) || (xhr.status == 304)){

			// Document オブジェクトを取得
			var xml_document = xhr.responseXML;

			// 出力テスト
			console.log(xml_document);

		// ------------------------------------------------------------
		// リクエスト失敗
		// ------------------------------------------------------------
		}else{
			console.log("リクエスト失敗");

		}
		break;
	}
};

// ------------------------------------------------------------
// 「GET メソッド」「接続先 URL」を指定
// ------------------------------------------------------------
xhr.open("GET" , "http://example.com/test.xml");

// ------------------------------------------------------------
// overrideMimeType メソッドをサポートしている
// ------------------------------------------------------------
if(xhr.overrideMimeType){

	// ------------------------------------------------------------
	// 「MIME Type」のオーバーライドを設定する
	// ------------------------------------------------------------
	xhr.overrideMimeType("application/xml");

}

// ------------------------------------------------------------
// XHR 通信を開始する
// ------------------------------------------------------------
xhr.send(null);
 

■受信したレスポンスボディを、任意のデータ型で取得する(HTML5 世代)

 
■responseType プロパティについて
 
取得したいデータ型を指定するには、responseType プロパティを使用します。
 
以下のタイプの指定が可能です。
 
指定する文字列 得られるデータ型 説明
"text" String テキストを読み込んで、文字列を得る
"document" Document XML 文書を読み込んで、Document オブジェクトを得る
"arraybuffer" ArrayBuffer バイナリを読み込んで、ArrayBuffer オブジェクトを得る
"blob" Blob バイナリを読み込んで、Blob オブジェクトを得る
"json" Object JSON 文書を読み込んで、Object オブジェクトを得る
 
■response プロパティについて
 
responseType プロパティで設定した結果を得るには、response プロパティを使用します。
 
■設定タイミングについて
 
open() メソッドから send() メソッドまでの間に設定します。
 
■取得可能なタイミングについて
 
XHR 通信が完了している場合、response プロパティにアクセス可能です。
 
XHR 通信が完了したか調べる方法については、こちらで解説しています。
 
■バイナリの読み込みについて
 
「x-user-defined 文字列」を使って読み込む方法もあります。
 
こちらで解説しています。
 
■取得例
 
バイナリを取得する(HTML5 世代)

// ------------------------------------------------------------
// XMLHttpRequest オブジェクトを作成
// ------------------------------------------------------------
var xhr = new XMLHttpRequest();

// ------------------------------------------------------------
// XHR 送信が成功したときに実行されるイベント
// ------------------------------------------------------------
xhr.onload = function(e){

	// 指定したデータ型でレスポンスボディの内容を取得
	var ary_buffer = xhr.response;

	// 出力テスト
	console.log(ary_buffer);
};

// ------------------------------------------------------------
// 「GET メソッド」「接続先 URL」を指定
// ------------------------------------------------------------
xhr.open("GET" , "http://example.com/download/test.dat");

// ------------------------------------------------------------
// レスポンスタイプを設定
// ------------------------------------------------------------
xhr.responseType = "arraybuffer";

// ------------------------------------------------------------
// XHR 通信を開始する
// ------------------------------------------------------------
xhr.send(null);
 
JSON 文書を読み込む(HTML5 世代)

// ------------------------------------------------------------
// Blob オブジェクトを作成(JSON 文書)
// ------------------------------------------------------------
var blob = new Blob(['{"aaa":0,"bbb":1,"ccc":2}'] , {type:"application/json"});

// Blob URL Scheme を生成する
var blob_url = window.URL.createObjectURL(blob);

// ------------------------------------------------------------
// XMLHttpRequest オブジェクトを作成
// ------------------------------------------------------------
var xhr = new XMLHttpRequest();

// ------------------------------------------------------------
// XHR 送信が成功したときに実行されるイベント
// ------------------------------------------------------------
xhr.onload = function(e){

	// 指定したデータ型でレスポンスボディの内容を取得
	var obj = xhr.response;

	// 出力テスト
	console.log(obj); // {aaa:0,bbb:1,ccc:2}
};

// ------------------------------------------------------------
// 「GET メソッド」「Blob URL」を指定
// ------------------------------------------------------------
xhr.open("GET" , blob_url);

// ------------------------------------------------------------
// レスポンスタイプを設定
// ------------------------------------------------------------
xhr.responseType = "json";

// ------------------------------------------------------------
// XHR 通信を開始する
// ------------------------------------------------------------
xhr.send(null);
 

■ファイルをダウンロードする(HTML5 世代)

 
■ Blob URL Scheme を使用する
 
Bolb オブジェクトを取得する方法については、こちらで解説しています。
 
ダウンロードの進捗状況の取得については、こちらで解説しています。
 
次に、Blob URL を生成します。
 
Blob URL については、こちらで解説しています。
 
最後に、download 属性を使って、ダウンロードを発生させます。
 
自動ダウンロードについては、こちらで解説しています。
 
Blob URL Scheme を使って、自動ダウンロードを開始する(HTML5 世代)

// ------------------------------------------------------------
// XMLHttpRequest オブジェクトを作成
// ------------------------------------------------------------
var xhr = new XMLHttpRequest();

// ------------------------------------------------------------
// 受信中に繰り返し実行されるイベント
// ------------------------------------------------------------
xhr.onprogress = function(e){

	// 出力テスト
	console.log("ダウンロード中:" + e.loaded + " / " + e.total);
};

// ------------------------------------------------------------
// XHR 送信が成功したときに実行されるイベント
// ------------------------------------------------------------
xhr.onload = function(e){

	// ------------------------------------------------------------
	// Blob URL を生成
	// ------------------------------------------------------------
	var blob_url = window.URL.createObjectURL(xhr.response);

	// ------------------------------------------------------------
	// HTMLAnchorElement オブジェクトを作成する
	// ------------------------------------------------------------
	var anchor = document.createElement("a");

	// ターゲットを設定
	anchor.target = "_blank";

	// Blob URLを指定
	anchor.href = blob_url;

	// デフォルトのファイル名を指定
	anchor.download = "test.dat";

	// ------------------------------------------------------------
	// ダウンロードを開始する
	// ------------------------------------------------------------
	document.body.appendChild(anchor);
	anchor.click();
	anchor.parentNode.removeChild(anchor);

};

// ------------------------------------------------------------
// 「GET メソッド」「接続先 URL」を指定(アンカーの href 属性の値を使用)
// ------------------------------------------------------------
xhr.open("GET" , "http://example.com/download/test.dat");

// ------------------------------------------------------------
// レスポンスタイプを設定
// ------------------------------------------------------------
xhr.responseType = "blob";

// ------------------------------------------------------------
// XHR 通信を開始する
// ------------------------------------------------------------
xhr.send(null);
 
■ Data URI Scheme を使用する
 
Blob URL 未対応ブラウザでは、代替として Data URI Scheme が利用できます。
 
ただし、大容量のファイルに弱く、長時間応答不能に陥る事があります。
 
任意のバイナリのダウンロードを開始する方法については、こちらで解説しています。
 

■受信中の進捗状況を調べる(HTML5 世代)

 
■受信の進捗イベントについて
 
onloadstart イベント自体は、送信処理の開始と同時に発生します。
 
実際に受信処理が開始されるのは、送信処理が完了した後です。
 
失敗に関係なく、必ず受信の完了を知るには、onloadend イベントを使用します。
 
イベント 説明 L
onloadstart ProgressEvent XHR 通信を開始したときに実行される 2
onprogress ProgressEvent 受信中に繰り返し実行される 2
onloadend ProgressEvent XHR 通信が完了したときに実行される(成功失敗に関係無く) 2
 
■受信の結果イベントについて
 
以下の4つのイベントは、同時に発行されることはありません。
 
よって1つでも欠けている場合、受信の完了を取りこぼします。
 
イベント 説明 L
onload ProgressEvent XHR 送信が成功したときに実行される(成功時のみ) 2
onerror ProgressEvent XHR 送信が失敗したときに実行される(失敗時のみ) 2
onabort ProgressEvent XHR 通信を中止すると実行される 2
ontimeout ProgressEvent タイムアウトエラー発生時に実行される 2
 
■ProgressEvent オブジェクトについて
 
登録したコールバック関数の引数から、ProgressEvent オブジェクトが得られます。
 
ProgressEvent オブジェクトには、以下のプロパティがあります。
 
プロパティ名説明
lengthComputableBoolean進捗のサイズ計算が可能であるかを取得
loadedNumberこれまでに完了した受信バイト数を取得
totalNumber全体の受信バイト数を取得
 
■受信結果を取得する例
 
受信結果を取得する(HTML5 世代)

// ------------------------------------------------------------
// XMLHttpRequest オブジェクトを作成
// ------------------------------------------------------------
var xhr = new XMLHttpRequest();

// ------------------------------------------------------------
// XHR 送信が成功したときに実行されるイベント
// ------------------------------------------------------------
xhr.onload = function(e){
	console.log("受信に成功");
};

// ------------------------------------------------------------
// XHR 送信が失敗したときに実行されるイベント
// ------------------------------------------------------------
xhr.onerror = function(e){
	console.log("受信に失敗");
};

// ------------------------------------------------------------
// XHR 通信を中止すると実行されるイベント
// ------------------------------------------------------------
xhr.onabort = function(e){
	console.log("XHR 通信を中止");
};

// ------------------------------------------------------------
// タイムアウトエラー発生時に実行されるイベント
// ------------------------------------------------------------
xhr.ontimeout = function(e){
	console.log("タイムアウトエラーが発生");
};

// ------------------------------------------------------------
// 「GET メソッド」「接続先 URL」を指定
// ------------------------------------------------------------
xhr.open("GET" , "http://example.com/download/test.dat");

// ------------------------------------------------------------
// XHR 通信を開始する
// ------------------------------------------------------------
xhr.send(null);
 
■受信中の進捗状況を取得する例
 
受信中の進捗状況を取得する(HTML5 世代)

// ------------------------------------------------------------
// XMLHttpRequest オブジェクトを作成
// ------------------------------------------------------------
var xhr = new XMLHttpRequest();

// ------------------------------------------------------------
// XHR 通信を開始したときに実行されるイベント
// ------------------------------------------------------------
xhr.onloadstart = function(e){
	console.log("受信を開始");
};

// ------------------------------------------------------------
// 受信中に繰り返し実行されるイベント
// ------------------------------------------------------------
xhr.onprogress = function(e){
	console.log("受信中: " + e.loaded + " / " + e.total);
};

// ------------------------------------------------------------
// XHR 通信が完了したときに実行されるイベント
// ------------------------------------------------------------
xhr.onloadend = function(e){
	console.log("受信が完了");
};

// ------------------------------------------------------------
// 「GET メソッド」「接続先 URL」を指定
// ------------------------------------------------------------
xhr.open("GET" , "http://example.com/download/test.dat");

// ------------------------------------------------------------
// XHR 通信を開始する
// ------------------------------------------------------------
xhr.send(null);
 
■ダウンロード用のプログレスバーを表示する例
 
ダウンロード用のプログレスバーを表示する(HTML5 世代)

<html>
  <body>

    <a href="http://example.com/download/test.dat" download="test.dat" id="my_anchor">ダウンロード</a>

    <div id="my_result" style="width:300px; text-align:right; margin-bottom:5px;"> --- </div>

    <div style="width:300px; height:10px; background:#fff; border:2px solid #000; line-height:0;">
	    <div id="my_progress" style="width:0px; height:10px; background:#ccc;"></div>
    </div>

    <script type="text/javascript">
    <!--

	// ------------------------------------------------------------
	// エレメントに文字列をセットして、テキストノードを構築する関数
	// ------------------------------------------------------------
	function ElementSetTextContent(element,str){
		if(element.textContent !== undefined){
			element.textContent = str;
		}
		if(element.innerText !== undefined){
			element.innerText = str;
		}
	}

	// ------------------------------------------------------------
	// 各エレメントを取得
	// ------------------------------------------------------------
	// id 属性が "my_anchor" であるエレメントを取得
	var anchor = document.getElementById("my_anchor");

	// id 属性が "my_result" であるエレメントを取得
	var result = document.getElementById("my_result");

	// id 属性が "my_progress" であるエレメントを取得
	var progress = document.getElementById("my_progress");

	// ------------------------------------------------------------
	// クリック時に実行されるイベント
	// ------------------------------------------------------------
	anchor.onclick = function(e){

		// ------------------------------------------------------------
		// クリックイベントのリッスンを終了
		// ------------------------------------------------------------
		anchor.onclick = null;

		// ------------------------------------------------------------
		// XMLHttpRequest オブジェクトを作成
		// ------------------------------------------------------------
		var xhr = new XMLHttpRequest();

		// ------------------------------------------------------------
		// サポートチェック
		// ------------------------------------------------------------
		if(xhr.responseType === undefined) return;
		if(!(window.URL)) return;

		// ------------------------------------------------------------
		// 受信中に繰り返し実行されるイベント
		// ------------------------------------------------------------
		xhr.onprogress = function(e){

			// リザルトを更新
			ElementSetTextContent(result,e.loaded + " / " + e.total + " Byte");

			// プログレスバーを更新
			if(e.lengthComputable){
				var percent = (e.loaded / e.total * 100);
				progress.style.width = (percent) + "%";
			}
		};

		// ------------------------------------------------------------
		// XHR 送信が成功したときに実行されるイベント
		// ------------------------------------------------------------
		xhr.onload = function(e){

			// Blob URL を生成
			var blob_url = window.URL.createObjectURL(xhr.response);

			// リンク先を Blob URL に変更
			anchor.href = blob_url;

			// アンカーをクリック
			anchor.click();
		};

		// ------------------------------------------------------------
		// 「GET メソッド」「接続先 URL」を指定(アンカーの href 属性の値を使用)
		// ------------------------------------------------------------
		xhr.open("GET" , anchor.href);

		// ------------------------------------------------------------
		// レスポンスタイプを設定
		// ------------------------------------------------------------
		xhr.responseType = "blob";

		// ------------------------------------------------------------
		// XHR 通信を開始する
		// ------------------------------------------------------------
		xhr.send(null);

		// ------------------------------------------------------------
		// デフォルトの動作をキャンセル
		// ------------------------------------------------------------
		if(e.preventDefault){
			// デフォルトの動作をキャンセル
			e.preventDefault();
		}else{
			// デフォルトの動作をキャンセル(非標準)
			return false;
		}
	};
    //-->
    </script>

  </body>
</html>
 

■最終的なリダイレクト先の URL アドレスを取得する(WHATWG 仕様)

 
■responseURL プロパティについて
 
最終的なリダイレクト先の URL アドレスを取得するには、responseURL プロパティを使用します。
 
取得結果に、ハッシュ部分(フラグメント識別子)は含まれません。
 
このプロパティは、一部のブラウザで対応しています。
 
Cross-Origin 特権付き XHR で利用すると便利です。(拡張機能用の JavaScript など)
 
最終的なリダイレクト先の URL アドレスを取得する(WHATWG 仕様)

// ------------------------------------------------------------
// XMLHttpRequest オブジェクトを作成
// ------------------------------------------------------------
var xhr = new XMLHttpRequest();

// ------------------------------------------------------------
// XHR 送信が成功したときに実行されるイベント
// ------------------------------------------------------------
xhr.onload = function(e){

	// 最終的なリダイレクト先の URL アドレスを取得する
	var final_url = xhr.responseURL;

	// 出力テスト
	console.log(final_url);
};

// ------------------------------------------------------------
// 「HEAD メソッド」「接続先 URL」を指定
// ------------------------------------------------------------
xhr.open("HEAD" , "http://t.co/lJ5lPCLZnG");

// ------------------------------------------------------------
// XHR 通信を開始する
// ------------------------------------------------------------
xhr.send(null);
 


 

CGI 側のデータ送受信処理について

 


■CGI 側のデータ送受信処理について

 
CGI 側でデータを受け取って結果を出力する方法として、以下のスクリプトを使用してみます。
 
 

■Perl を使用する

 
Perl を利用して、パラメータの受信とパラメータの出力処理を行ってみます。
 

■GET メソッドを使った受信について

 
GET メソッドであるか調べるには、$ENV{'REQUEST_METHOD'}"GET" であるか比較します。
 
リクエストメソッドを調べる

#!/usr/local/bin/perl

# GETメソッドであるか調べる
if ($ENV{'REQUEST_METHOD'} eq "GET") {

}
 
GET メソッドであれば、$ENV{'QUERY_STRING'} を取得します。URL 文字列の "?" 以降の文字列を取得することができます。
 
コンテンツタイプが「application/x-www-form-urlencoded」であれば、
 
さらに "&" で区切って、"変数名=値" を取り出します。
 
さらに "=" で区切って、変数名と値を分離し、連想配列に格納します。
 
受信したパラメータから変数を作成する

#!/usr/local/bin/perl


# パラメータを格納する為の連想配列
%request_param;

# GETメソッドであるか調べる
if ($ENV{'REQUEST_METHOD'} eq "GET") {
	
	# URL の ? 以降の文字列を取得する
	$query = $ENV{'QUERY_STRING'};

	# "&" で区切って、配列に格納する
	@list = split(/&/,$query);
	foreach(@list) {

		# "=" で区切る
		($k,$v) = split(/=/,$_);

		# URL デコードを行い値を連想配列に格納する
		$request_param{"$k"} = UrlDecode($v);
	}
}


#// -----------------------------------------------------
#// URLデコード
#// -----------------------------------------------------
sub UrlDecode {
	my $str = @_[0];
	$str =~ tr/+/ /;
	$str =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack('H2', $1)/eg;
	return $str;
}
 

■POST メソッドを使った受信について

 
POST メソッドであるか調べるには、$ENV{'REQUEST_METHOD'}"POST" であるか比較します。
 
リクエストメソッドを調べる

#!/usr/local/bin/perl

# POSTメソッドであるか調べる
if ($ENV{'REQUEST_METHOD'} eq "POST") {

}
 
POST メソッドであれば、標準入力を使用してパラメータを取得します。
 
コンテンツタイプが「application/x-www-form-urlencoded」であれば、
 
さらに "&" で区切って、"変数名=値" を取り出します。
 
さらに "=" で区切って、変数名と値を分離し、連想配列に格納します。
 
受信したパラメータから変数を作成する

#!/usr/local/bin/perl


# パラメータを格納する為の連想配列
%request_param;

# POSTメソッドであるか調べる
if ($ENV{'REQUEST_METHOD'} eq "POST") {
	
	# 標準入力からパラメータを取得する
	read (STDIN, $query, $ENV{'CONTENT_LENGTH'});

	# "&" で区切って、配列に格納する
	@list = split(/&/,$query);
	foreach(@list) {

		# "=" で区切る
		($k,$v) = split(/=/,$_);

		# URL デコードを行い値を連想配列に格納する
		$request_param{"$k"} = UrlDecode($v);

	}
}


#// -----------------------------------------------------
#// URLデコード
#// -----------------------------------------------------
sub UrlDecode {
	my $str = @_[0];
	$str =~ tr/+/ /;
	$str =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack('H2', $1)/eg;
	return $str;
}
 

■JavaScript 側で読み込めるように文字列を出力する

 
文字列を出力するには、print 命令を使用します。
 
HTTP ヘッダには、出力したいデータのコンテンツタイプを指定します。
 
コンテンツタイプとデータの出力例です。
 
文字列を出力する

#!/usr/local/bin/perl


# Content-type を出力
print "Content-type:text/plain\n";

# 改行のみでヘッダの終了
print "\n";

# 文字列を出力
print "Hallo World!!";
 
HTML 文字列を出力する

#!/usr/local/bin/perl


# Content-type を出力
print "Content-type:text/html\n";

# 改行のみでヘッダの終了
print "\n";

# HTML 文字列をヒアドキュメントで出力
print << "EOF";
<html>
<body>
	<b>Hallo World!!<b>
</body>
</html>
EOF
# ---
 
application/x-www-form-urlencoded を出力する

#!/usr/local/bin/perl


# Content-type を出力
print "Content-type:application/x-www-form-urlencoded\n";

# 改行のみでヘッダの終了
print "\n";

# 変数
$user = "hanako";
$age = 16;
$blood = "o";

# パラメータを出力
print "user=" . "$user";
print "&";
print "age=" . "$age";
print "&";
print "blood=" . "$blood";
 
JSON文字列を出力する

#!/usr/local/bin/perl


# Content-type を出力
print "Content-type:application/json\n";

# 改行のみでヘッダの終了
print "\n";

# 変数
$user = "hanako";
$age = 16;
$blood = "o";

# パラメータを出力
print "{";
print "\"user\":\"" . "$user" . "\",";
print "\"age\":" . "$age" . ",";
print "\"blood\":\"" . "blood" . "\"";
print "}";
 
 

■PHP を使用する

 
PHP を利用して、パラメータの受信とパラメータの出力処理を行ってみます。
 

■GET メソッドを使った受信について

 
GET メソッドであるか調べるには、$_SERVER['REQUEST_METHOD']"GET" であるか比較します。
 
リクエストメソッドを調べる

<?php

	# GETメソッドであるか調べる
	if ($_SERVER['REQUEST_METHOD'] == "GET") {

	}

?>
 
クライアントから GET メソッドで送信されたパラメータを取得するには、$_GETを使用します。
 
コンテンツタイプが「application/x-www-form-urlencoded」であれば、
 
中身は連想配列となっています。
 
GETメソッド のパラメータを取得する

<?php

	# パラメータを格納する為の連想配列
	$request_param;

	# GETメソッドであるか調べる
	if ($_SERVER['REQUEST_METHOD'] == "GET") {

		foreach ( $_GET as $k => $v){

			# URL デコードを行い値を連想配列に格納する
			$request_param{"$k"} = urldecode($v);
		}
	}

?>
 

■POST メソッドを使った受信について

 
POST メソッドであるかを取得するには、$_SERVER['REQUEST_METHOD']"POST" であるかを調べます。
 
リクエストメソッドを調べる

<?php

	# POSTメソッドであるか調べる
	if ($_SERVER['REQUEST_METHOD'] == "POST") {

	}

?>
 
クライアントから POST メソッドで送信されたパラメータを取得するには、$_POSTを使用します。
 
コンテンツタイプが「application/x-www-form-urlencoded」であれば、
 
中身は連想配列となっています。
 
POSTメソッド のパラメータを取得する

<?php

	# パラメータを格納する為の連想配列
	$request_param;

	# POSTメソッドであるか調べる
	if ($_SERVER['REQUEST_METHOD'] == "POST") {

		foreach ( $_POST as $k => $v){

			# URL デコードを行い値を連想配列に格納する
			$request_param{"$k"} = urldecode($v);
		}
	}

?>
 

■JavaScript 側で読み込めるように文字列を出力する

 
文字列を出力するには、echo 命令を使用します。
 
HTTP ヘッダには、出力したいデータのコンテンツタイプを指定します。
 
コンテンツタイプとデータの出力例です。
 
文字列を出力する

<?php

	# Content-type を出力
	header("Content-type:text/plain");

	# 文字列を出力
	echo "Hallo World!!";

?>
 
HTML 文字列を出力する

<?php

	# Content-type を出力
	header("Content-type:text/html");

	# HTML 文字列をヒアドキュメントで出力
	print <<<EOF
<html>
<body>
	<b>Hallo World!!<b>
</body>
</html>
EOF;

?>
 
application/x-www-form-urlencoded を出力する

<?php

	# Content-type を出力
	header("Content-type:application/x-www-form-urlencoded");

	# 変数
	$user = "hanako";
	$age = 16;
	$blood = "o";

	# パラメータを出力
	echo "user=" . $user;
	echo "&";
	echo "age=" . $age;
	echo "&";
	echo "blood=" . $blood;

?>
 
JSON文字列を出力する

<?php

	# Content-type を出力
	header("Content-type:application/json");

	# 変数
	$user = "hanako";
	$age = 16;
	$blood = "o";

	# パラメータを出力
	echo "{";
	echo "\"user\":\"" . $user . "\",";
	echo "\"age\":" . $age . ",";
	echo "\"blood\":\"" . $blood . "\"";
	echo "}";

?>
 
 

■Ruby を使用する

 
Ruby を利用して、パラメータの受信とパラメータの出力処理を行ってみます。
 

■GET メソッドを使った受信について

 
GET メソッドであるか調べるには、ENV['REQUEST_METHOD']"GET" であるか比較します。
 
リクエストメソッドを調べる

#!/usr/local/bin/ruby

# GETメソッドであるか調べる
if ENV['REQUEST_METHOD'] == "GET" then

end
 
GET メソッドであれば、ENV['QUERY_STRING'] を取得します。URL 文字列の "?" 以降の文字列を取得することができます。
 
コンテンツタイプが「application/x-www-form-urlencoded」であれば、
 
さらに "&" で区切って、"変数名=値" を取り出します。
 
さらに "=" で区切って、変数名と値を分離し、連想配列に格納します。
 
受信したパラメータを連想配列に格納する

#!/usr/local/bin/ruby


# ライブラリをロード
require 'cgi'

# パラメータを格納する為の連想配列
request_param = Hash.new

# GETメソッドであるか調べる
if ENV['REQUEST_METHOD'] == "GET" then

	# URL の ? 以降の文字列を取得する
	query = ENV['QUERY_STRING']

	# "&" で区切る
	for q in query.split("&") do
		# "=" で区切る
		k, v  = q.split("=",2)

		# URL デコードを行い連想配列に格納
		request_param[k] = CGI.unescape(v);
	end
end
 

■POST メソッドを使った受信について

 
POST メソッドであるか調べるには、ENV['REQUEST_METHOD']"POST" であるか比較します。
 
リクエストメソッドを調べる

#!/usr/local/bin/ruby

# POSTメソッドであるか調べる
if (ENV['REQUEST_METHOD'] == "POST") {

}
 
POST メソッドであれば、標準入力を使用してパラメータを取得します。
 
コンテンツタイプが「application/x-www-form-urlencoded」であれば、
 
さらに "&" で区切って、"変数名=値" を取り出します。
 
さらに "=" で区切って、変数名と値を分離し、連想配列に格納します。
 
受信したパラメータを連想配列に格納する

#!/usr/local/bin/ruby


# ライブラリをロード
require 'cgi'

# パラメータを格納する為の連想配列
request_param = Hash.new

# POSTメソッドであるか調べる
if ENV['REQUEST_METHOD'] == "POST" then

	# 標準入力からパラメータを取得する
	query = STDIN.read(ENV['CONTENT_LENGTH'].to_i)

	# "&" で区切る
	for q in query.split("&") do
		# "=" で区切る
		k, v  = q.split("=",2)

		# URL デコードを行い連想配列に格納
		request_param[k] = CGI.escape(v);
	end
end
 

■JavaScript 側で読み込めるように文字列を出力する

 
文字列を出力するには、print 命令を使用します。
 
HTTP ヘッダには、出力したいデータのコンテンツタイプを指定します。
 
コンテンツタイプとデータの出力例です。
 
文字列を出力する

#!/usr/local/bin/ruby

# Content-type を出力
print "Content-Type: text/plain\n"

# 改行のみでヘッダの終了
print "\n"

# パラメータを出力
print "Hallo World!!"
 
HTML 文字列を出力する

#!/usr/local/bin/ruby

# Content-type を出力
print "Content-Type: text/html\n"

# 改行のみでヘッダの終了
print "\n"

# HTML 文字列をヒアドキュメントで出力
print <<EOF
<html>
<body>
	<b>Hallo World!!<b>
</body>
</html>
EOF
 
application/x-www-form-urlencoded を出力する

#!/usr/local/bin/ruby

# Content-type を出力
print "Content-Type: application/x-www-form-urlencoded\n"

# 改行のみでヘッダの終了
print "\n"

# 変数
user = "hanako"
age = 16
blood = "o"

# パラメータを出力
print "user=" + user
print "&"
print "age=" + age.to_s
print "&"
print "blood=" + blood
 
JSON文字列を出力する

#!/usr/local/bin/ruby

# Content-type を出力
print "Content-Type: application/json\n"

# 改行のみでヘッダの終了
print "\n"

# 変数
user = "hanako"
age = 16
blood = "o"

# パラメータを出力
print "{"
print "\"user\":\"" + user + "\","
print "\"age\":" + age.to_s + ","
print "\"blood\":\"" + blood + "\""
print "}"
 
 

■Python を使用する

 
Python を利用して、パラメータの受信とパラメータの出力処理を行ってみます。
 

■GET メソッドを使った受信について

 
GET メソッドであるか調べるには、os.getenv('REQUEST_METHOD')"GET" であるか比較します。
 
リクエストメソッドを調べる

#!/usr/local/bin/python
# coding: utf-8


# ライブラリをロード
import os

# GETメソッドであるか調べる
if os.getenv('REQUEST_METHOD') == "GET" :
	print "GET METHOD"

 
GET メソッドであれば、os.getenv('QUERY_STRING') を取得します。URL 文字列の "?" 以降の文字列を取得することができます。
 
コンテンツタイプが「application/x-www-form-urlencoded」であれば、
 
さらに "&" で区切って、"変数名=値" を取り出します。
 
さらに "=" で区切って、変数名と値を分離し、連想配列に格納します。
 
受信したパラメータを連想配列に格納する

#!/usr/local/bin/python
# coding: utf-8


# ライブラリをロード
import os
import urllib

# パラメータを格納する為の連想配列
request_param = dict()

# GETメソッドであるか調べる
if os.getenv('REQUEST_METHOD') == "GET" :

	# URL の ? 以降の文字列を取得する
	query = os.getenv('QUERY_STRING')

	# "&" で区切る
	for q in query.split('&') :
		# "=" で区切る
		k, v  = q.split("=",2)

		# URL デコードを行い連想配列に格納
		request_param[k] = urllib.unquote(v)
	

 

■POST メソッドを使った受信について

 
POST メソッドであるか調べるには、os.getenv('REQUEST_METHOD')"POST" であるか比較します。
 
リクエストメソッドを調べる

#!/usr/local/bin/python
# coding: utf-8


# ライブラリをロード
import os

# POSTメソッドであるか調べる
if os.getenv('REQUEST_METHOD') == "POST" :
	print "POST METHOD"

 
POST メソッドであれば、標準入力を使用してパラメータを取得します。
 
コンテンツタイプが「application/x-www-form-urlencoded」であれば、
 
さらに "&" で区切って、"変数名=値" を取り出します。
 
さらに "=" で区切って、変数名と値を分離し、連想配列に格納します。
 
受信したパラメータを連想配列に格納する

#!/usr/local/bin/python
# coding: utf-8


# ライブラリをロード
import os
import sys
import urllib

# パラメータを格納する為の連想配列
request_param = dict()

# POSTメソッドであるか調べる
if os.getenv('REQUEST_METHOD') == "POST" :

	# 標準入力からパラメータを取得する
	query = sys.stdin.read(int(os.getenv('CONTENT_LENGTH')))

	# "&" で区切る
	for q in query.split('&') :
		# "=" で区切る
		k, v  = q.split("=",2)

		# URL デコードを行い連想配列に格納
		request_param[k] = urllib.unquote(v)
	

 

■JavaScript 側で読み込めるように文字列を出力する

 
文字列を出力するには、「sys.stdout.write() メソッド」を使用します。
 
HTTP ヘッダには、出力したいデータのコンテンツタイプを指定します。
 
コンテンツタイプとデータの出力例です。
 
文字列を出力する(文字コードを UTF-8 とする)

#!/usr/local/bin/python
# coding: utf-8


# ライブラリをロード
import sys

# Content-type を出力
sys.stdout.write("Content-Type: text/plain\n\n")

# パラメータを出力
sys.stdout.write("Hallo World!!")
 
HTML 文字列を出力する(文字コードを UTF-8 とする)

#!/usr/local/bin/python
# coding: utf-8


# ライブラリをロード
import sys

# Content-type を出力
sys.stdout.write("Content-Type: text/html\n\n")

# HTML 文字列をトリプルクォートで囲んで出力
sys.stdout.write("""
<html>
<body>
	<b>Hallo World!!<b>
</body>
</html>
""")
 
application/x-www-form-urlencoded を出力する(文字コードを UTF-8 とする)

#!/usr/local/bin/python
# coding: utf-8


# ライブラリをロード
import sys

# Content-type を出力
sys.stdout.write("Content-Type: application/x-www-form-urlencoded\n\n")

# 変数
user = "hanako"
age = 16
blood = "o"

# パラメータを出力
sys.stdout.write("user=" + user)
sys.stdout.write("&")
sys.stdout.write("age=" + str(age))
sys.stdout.write("&")
sys.stdout.write("blood=" + blood)
 
JSON文字列を出力する(文字コードを UTF-8 とする)

#!/usr/local/bin/python
# coding: utf-8


# ライブラリをロード
import sys

# Content-type を出力
sys.stdout.write("Content-Type: application/json\n\n")

# 変数
user = "hanako"
age = 16
blood = "o"

# パラメータを出力
sys.stdout.write("{")
sys.stdout.write("\"user\":\"" + user + "\",")
sys.stdout.write("\"age\":" + str(age) + ",")
sys.stdout.write("\"blood\":\"" + blood + "\"")
sys.stdout.write("}")
 

 

 

クロスサイト通信について

 
 

■クロスサイト通信とは?

 
■オリジン(Origin)について
 
プロトコルドメインポート番号」の3つを合わせたものを、オリジンといいます。
 
 
■同一生成元ポリシー (Same-Origin Policy) による制限
 
任意の Web ページから、別オリジン下に格納されているリソースを、読み取りアクセスする事はできません。
 
例えば、XMLHttpRequest 通信は、失敗します。
 
■クロスサイト通信とは?
 
他サイトとのデータの送受信を実現する事を、クロスサイト通信といいます。
 
クロスオリジン通信や、クロスドメイン通信と呼ばれる事もあります。
 
 

■ JSON with padding (JSONP) について

 
■ <script> 要素の特性
 
<script> 要素には、同一生成元ポリシー (Same-Origin Policy) はありません。
 
どのサイトに存在する JavaScript ファイルでも、読み込んで実行する事ができます。
 
■ JSONP とは?
 
<script> タグのリンク先に、CGI のページを指定します。
 
CGI 側は、任意のデータを含む、JavaScript のコードを出力します。
 
これで、クロスサイト通信が実現できます。
 
このクロスサイト通信の手法を、JSONP と言います。
 
JSONP は 「JSON with padding」の略です。
 
JSONP は、主要ブラウザで動作させる事ができます。
 
ソーシャルサイトの API サービスなど幅広く利用されています。
 

■クライアント側の処理について

 
1.受信用のコールバック関数を用意する
 
グローバルな空間に、受信用のコールバック関数を用意します。
 
ここでは、ExternalCallback とします。
 
この関数は、サーバー側が生成する JavaScript コードから実行されます。
 
受信用のグローバルなコールバック関数を用意する

window.ExternalCallback = function (param){

	console.log("通信が完了した:" + param);

};
 
2.HTMLScriptElement オブジェクトを作成する
 
document.createElement() メソッドを使って、HTMLScriptElement オブジェクトを作成します。
 
HTMLScriptElement オブジェクトを作成する(クライアント側)

// HTMLScriptElement オブジェクトを作成する
var script = document.createElement("script");
 
3.アドレス先と送信パラメータを指定する
 
src プロパティに、CGI の URL アドレスを設定します。
 
サーバー側にデータを送信したい場合は、URL アドレスにクエリ文字列を埋め込みます。
 
サーバー側に、コールバック関数名を送信します。
 
「callback=ExternalCallback」という値を埋め込みます。
 
src プロパティに、CGI の URL アドレスを指定する(クライアント側)

// CGI の URL アドレスをセット
script.src = "http://example.com/api/test.cgi";
 
「user=taro」「age=18」「blood=b」という3つのパラメータを渡す(クライアント側)

// CGI の URL アドレスをセット
script.src = "http://example.com/api/test.cgi?user=taro&age=18&blood=b";
 
「callback=ExternalCallback」というパラメータを渡す(クライアント側)

// CGI の URL アドレスをセット
script.src = "http://example.com/api/test.cgi?callback=ExternalCallback";
 
4.DOM のノードリストに登録してスクリプトを実行する
 
DOM のノードリストに登録すると、通信が開始されます。
 
ここから、CGI との通信が終了するまでは、非同期実行となります。
 
コールバック関数が実行されれば、通信が完了した事がわかります。
 
また、引数からデータを得る事ができます。
 
body のノードに登録して HTMLScriptElement を動作させる

// ------------------------------------------------------------
// 受信用のグローバルなコールバック関数
// ------------------------------------------------------------
window.ExternalCallback = function (param){

	console.log("通信が完了した:" + param);

};

// ------------------------------------------------------------
// HTMLScriptElement オブジェクトを作成する
// ------------------------------------------------------------
var script = document.createElement("script");

// ------------------------------------------------------------
// CGI の URL アドレスをセット
// ------------------------------------------------------------
script.src = "http://example.com/api/test.cgi?callback=ExternalCallback";

// ------------------------------------------------------------
// BODY 要素のノードリストに登録する(通信開始)
// ------------------------------------------------------------
document.body.appendChild(script);
 
■クライアント側のセキュリティについて
 
<script> 要素は、どのサイトに存在する JavaScript ファイルでも、読み込んで実行する事ができます。
 
不特定のアドレスが指定されないように注意します。
 

■サーバー側の処理について

 
1.JSON テキストを出力する
 
デフォルトでは、JSON テキストを出力するようにします。
 
任意のデータを JSON テキスト形式で出力する (サーバー側)

{"a":0,"b":1,"c":2}
 
2.クライアントから受け取ったコールバック関数を実行する
 
URL アドレスのクエリ引数に、コールバック関数名が指定されているか確認します。
 
指定されている場合、その関数を実行する JavaScript コードを出力します。
 
コールバック関数の引数には、JSON テキストをそのまま出力します。
 
JavaScript コードを出力する「指定されたコールバック関数を実行し、引数からデータを渡す」 (サーバー側)

ExternalCallback( {"a":0,"b":1,"c":2} );
 

■ JSONP による様々なサービスを確認する

 
JSONP は、様々なサービスで利用されています。
 
URL から「callback=コールバック関数名」というパラメータを渡します。
 
サーバー側では、指定したコールバック関数名を実行する、JavaScript コードが生成されています。
 
■ はてなブックマークエントリー情報を取得する API
 
 
■ Twitter にて "JavaScript" で検索した際の情報を取得する API (終了済)
 
 
■使用例
 
はてなブックマークエントリー情報を取得する

// ------------------------------------------------------------
// クエリー
// ------------------------------------------------------------
var query = "http://hakuhin.jp/js.html";

// ------------------------------------------------------------
// HTMLScriptElement オブジェクトを作成する
// ------------------------------------------------------------
var script = document.createElement("script");

// ------------------------------------------------------------
// 受信用コールバック用関数を生成
// ------------------------------------------------------------
window.ExternalCallback = function (param){

	// ------------------------------------------------------------
	// HTMLScriptElement オブジェクトをノードリストから除外する
	// ------------------------------------------------------------
	if(script.parentNode){
		script.parentNode.removeChild(script);
	}

	// ------------------------------------------------------------
	// 受信用コールバック関数を破棄する
	// ------------------------------------------------------------
	try{
		delete window.ExternalCallback;
	}catch(e){
		window.ExternalCallback = null;
	}

	// ------------------------------------------------------------
	// 出力テスト
	// ------------------------------------------------------------
	console.log(param);
};

// ------------------------------------------------------------
// CGI の URL アドレスをセット
// ------------------------------------------------------------
script.src = 'http://b.hatena.ne.jp/entry/jsonlite/?url=' + encodeURIComponent(query) + '&callback=ExternalCallback';

// ------------------------------------------------------------
// BODY のノードリストに登録する(通信開始)
// ------------------------------------------------------------
document.body.appendChild(script);
 
はてなブックマークエントリー情報を複数同時に要求する

// ------------------------------------------------------------
// 検索したいクエリーリスト
// ------------------------------------------------------------
var query_list = [
	"http://hakuhin.jp/as.html",
	"http://hakuhin.jp/as3.html",
	"http://hakuhin.jp/js.html"
];

// ユニーク ID
var unique_id = 0;

var i;
var num = query_list.length;
for(i=0;i < num;i++){

	// クエリー
	var query = query_list[i];

	// 匿名関数内で実行
	(function(){

		// ------------------------------------------------------------
		// ユニーク(唯一)な名前を用意
		// ------------------------------------------------------------
		var callback_name = "ExternalCallback_" + unique_id;
		unique_id ++;

		// ------------------------------------------------------------
		// HTMLScriptElement オブジェクトを作成する
		// ------------------------------------------------------------
		var script = document.createElement("script");

		// ------------------------------------------------------------
		// 受信用コールバック用関数を生成
		// ------------------------------------------------------------
		window[callback_name] = function (param){

			// ------------------------------------------------------------
			// HTMLScriptElement オブジェクトをノードリストから除外する
			// ------------------------------------------------------------
			if(script.parentNode){
				script.parentNode.removeChild(script);
			}

			// ------------------------------------------------------------
			// 受信用コールバック関数を破棄する
			// ------------------------------------------------------------
			try{
				delete window[callback_name];
			}catch(e){
				window[callback_name] = null;
			}

			// ------------------------------------------------------------
			// 出力テスト
			// ------------------------------------------------------------
			console.log(param);
		};

		// ------------------------------------------------------------
		// CGI の URL アドレスをセット
		// ------------------------------------------------------------
		script.src = 'http://b.hatena.ne.jp/entry/jsonlite/?url=' + encodeURIComponent(query) + '&callback=' + callback_name;

		// ------------------------------------------------------------
		// BODY のノードリストに登録する(通信開始)
		// ------------------------------------------------------------
		document.body.appendChild(script);

	})();

}
 
 

■「クロスオリジンリソースシェアリング(CORS)」について

 
XMLHttpRequest Level2」に対応しているブラウザは、「Cross-Origin Resource Sharing(CORS)」に対応しています。
 
CORS の仕様については、こちらで解説しています。
 
Internet Explorer 9 以前では利用できません。
 
Internet Explorer 8 と 9 では、変わりに XDomainRequest クラスが利用できます。
 
■リソースシェアリングを許可するには?(サーバー側の処理)
 
レスポンスヘッダに、アクセスコントロールを追加します。
 
必須となるのは、Access-Control-Allow-Origin ヘッダです。
 
すべてのサイトから、リソースシェアリングを許す

Access-Control-Allow-Origin: *
 

■クライアント側の仕様について

 
■クロスオリジン通信を行った場合
 
クロスオリジン通信を行った場合、リクエストヘッダに Origin 情報が、自動的に追加されます。
 
改変や阻止をする事はできません。
 
Origin ヘッダには、リクエスト側の生成元(オリジン)情報が付加されます。
 
ヘッダフィールド名説明
Originリクエスト側のオリジン情報を、サーバ側に通知する(自動)
 
■プリフライトリクエストについて
 
クロスオリジン通信を行ない」かつ、「安全ではない HTTP メソッドを指定した」か「リクエストヘッダを改変した」場合、特殊な XMR 通信に変化します。
 
まず、OPTIONS メソッドの通信が、自動的に発生します。
 
この事前リクエストを、プリフライトリクエストといいます。
 
もしサーバーが許可した場合、続けて通常の XHR 通信が発生します。
 
もしサーバーが拒絶した場合、この時点で XHR 通信は失敗します。
 
■プリフライトリクエストが発生した場合
 
プリフライトが発生した場合、リクエストヘッダに以下の情報が、自動的に追加されます。
 
改変や阻止をする事はできません。
 
ヘッダフィールド名説明
Access-Control-Request-Methodメインの HTTP メソッドの種類を、サーバ側に通知する(自動)
Access-Control-Request-Headers改変したリクエストヘッダの種類を、サーバ側に通知する(自動)
 
■ブラウザを使って通信内容を確認する
 
ブラウザの開発者向けツールを使用すると、通信内容を確認する事ができます。
 
使用方法は、こちらで解説しています。
 
通信エラーが発生した場合、コンソールに必要な手続きが表示され、参考になります。
 
■プリフライトと関係のあるサーバー側の設定
 
プリフライトは、サーバーの以下のヘッダと関係があります。
 
ヘッダフィールド名説明
Access-Control-Allow-Methods許可する HTTP メソッドの種類を設定する
Access-Control-Allow-Headers許可するリクエストヘッダの種類を設定する
 

■ XDomainRequest について (Internet Explorer 専用)

 
XDomainRequest は、Access-Control-Allow-Origin ヘッダに対応しています。
 
詳しい仕様は、MSDN が参考になります。
 
http://msdn.microsoft.com/en-us/library/ie/cc288060(v=vs.85).aspx
 
■使用例
 
XDomainRequest を使用する

// XDomainRequest をサポートしている
if(window.XDomainRequest){

	// ------------------------------------------------------------
	// XDomainRequest オブジェクトを作成する
	// ------------------------------------------------------------
	var xdr = new XDomainRequest();

	// ------------------------------------------------------------
	// 通信に成功すると実行されるイベント
	// ------------------------------------------------------------
	xdr.onload = function (){
		// コンテンツタイプを取得する
		console.log(xdr.contentType );

		// レスポンスボディを取得する
		console.log(xdr.responseText );
	};

	// ------------------------------------------------------------
	// 通信に失敗すると実行されるイベント
	// ------------------------------------------------------------
	xdr.onerror = function (){

	};

	// ------------------------------------------------------------
	// 通信中に繰り返し実行されるイベント
	// ------------------------------------------------------------
	xdr.onprogress = function (){

	};

	// ------------------------------------------------------------
	// タイムアウトが発生すると実行されるイベント
	// ------------------------------------------------------------
	xdr.ontimeout = function (){

	};

	// ------------------------------------------------------------
	// タイムアウトと判断する時間を設定する(単位:ミリ秒)(デフォルトは 0)
	// ------------------------------------------------------------
	xdr.timeout = 0;

	// ------------------------------------------------------------
	// 「HTTP メソッドを指定する」「アクセス先 URL を指定する」
	// ------------------------------------------------------------
	var method = "POST";
	var url = "http://example.com/test.cgi";
	xdr.open( method , url );

	// ------------------------------------------------------------
	// 「送信データを指定する」「通信を開始する」
	// ------------------------------------------------------------
	var send_data = "Hello World !!";
	xdr.send( send_data );

	// ------------------------------------------------------------
	// 「通信を中止する」
	// ------------------------------------------------------------
	// xdr.abort();

}