XMLHttpRequest

出典: フリー百科事典『ウィキペディア(Wikipedia)』
移動: 案内検索

XMLHttpRequest (XHR) は、JavaScriptなどのウェブブラウザ搭載のスクリプト言語サーバとのHTTP通信を行うための、組み込みオブジェクトAPI)である。

すでに読み込んだページからさらにHTTPリクエストを発することができ、ページ遷移することなしにデータを送受信できるAjaxの基幹技術である。

XMLHttpRequestを利用したWebアプリケーションは非常に多く存在し、例として、Google マップFacebookなどが挙げられる。

歴史[編集]

XMLHttpRequestは、マイクロソフトOutlook Web Access 2000のダイナミックHTMLによるウェブインターフェースに活用するため、1999年公開のInternet Explorer 5においてActiveXオブジェクトとして実装したのが始まりである[1]。その後、2001年Mozillaプロジェクトがこれと互換性のある組み込みオブジェクトをMozilla 0.9.7およびNetscape 7で実装し、アップル2004年Safari 1.2でMozillaと同様の組み込みオブジェクトを実装し始めた[2]

このように徐々にInternet Explorer以外のブラウザにも実装されていったXMLHttpRequestは、2005年Ajaxによって一躍有名になった。オペラ・ソフトウェアも同年、組み込みオブジェクトとしてXMLHttpRequestを実装したOpera 8をリリースするなど、XMLHttpRequestはスクリプトの実行環境がある多くのブラウザで実装された。またマイクロソフト2006年リリースのInternet Explorer 7で、ユーザーがActiveXを無効にしていてもAjaxアプリケーションを利用できるよう、XMLHttpRequestを組み込みオブジェクトとして標準実装した[3]

同様の機能を有するオブジェクトが定義されたDOM Level 3 Load and Save Specificationが2004年4月にW3C勧告となっているが、すでにXMLHttpRequestは多くのウェブブラウザで実装されているデファクトスタンダードとなっており、W3Cでは現在その仕様の標準化を進めている。

オブジェクトの構成[編集]

Level 1[編集]

Level 1は全ての主要なブラウザの最新版では実装されている。

  • メソッド
    • abort
    • getAllResponseHeaders
    • getResponseHeader
    • open
    • send
    • setRequestHeader
  • プロパティ
    • onreadystatechange
    • readyState
      • 0 = UNSENT
      • 1 = OPENED
      • 2 = HEADERS_RECEIVED
      • 3 = LOADING
      • 4 = DONE
    • responseText
    • responseXML
    • status
    • statusText

Level 2[編集]

XMLHttpRequest Level 2では以下のプロパティとメソッドが追加になっている。Firefox, Google Chrome, Safariで実装が進んでいる。

  • メソッド
    • overrideMimeType
  • プロパティ
    • timeout
    • asBlob
    • followRedirects
    • withCredentials
    • upload
    • responseBody
    • onloadstart
    • onprogress
    • onabort
    • onerror
    • onload
    • ontimeout
    • onloadend

利用法[編集]

オブジェクトの作成[編集]

Internet Explorer 5および6ではActiveXオブジェクトでしか存在しないため、以下のようなフォールバックコードが多用される。

var xhr;
if (XMLHttpRequest) {
  // 組み込みオブジェクトとして定義されていればそれを利用
  xhr = new XMLHttpRequest();
} else {
  // さもなくばActiveXオブジェクトを利用
  try {
    xhr = new ActiveXObject('MSXML2.XMLHTTP.6.0');
  } catch (e) {
    try {
      xhr = new ActiveXObject('MSXML2.XMLHTTP.3.0');
    } catch (e) {
      try {
        xhr = new ActiveXObject('MSXML2.XMLHTTP');
      } catch (e) {
        alert("ActiveXを有効にしてください");
      }
    }
  }
}

MSXMLのどのバージョンを利用するかについて、マイクロソフトのXMLチームはベストとして6.0、代替として3.0を推奨している[4]

また、見やすさと利便性を考慮してこのようなコードも使われる。 関数化により簡単に扱えるようにし、 return文は関数を終了する働きを持っていることを利用して見やすさを向上させている。

function createXMLHttpRequest(){
	if(window.XMLHttpRequest){return new XMLHttpRequest()}
	if(window.ActiveXObject){
		try{return new ActiveXObject("Msxml2.XMLHTTP.6.0")}catch(e){}
		try{return new ActiveXObject("Msxml2.XMLHTTP.3.0")}catch(e){}
		try{return new ActiveXObject("Microsoft.XMLHTTP")}catch(e){}
 
	}
	return false;
};

さらに、このように圧縮したコードを書くこともできる。

function createXMLHttpRequest(a,e,i){
	if(XMLHttpRequest){return new XMLHttpRequest()}
	if(ActiveXObject){a="Msxml2.XMLHTTP.";a=["Microsoft.XMLHTTP",a+"3.0",a+"6.0"];
	for(i=3;i--;){try{return new ActiveXObject(a[i])}catch(e){}}
	}return !1
};

GET[編集]

xhr.onreadystatechange = function() {
  if (xhr.readyState == 4) { // DONE
    if (xhr.status == 200) { // OK
      alert(xhr.responseText);
    } else {
      alert("status = " + xhr.status);
    } 
  }
}
xhr.open("GET", "hoge.txt");
xhr.send();

POST[編集]

xhr.onreadystatechange = function() {
  if (xhr.readyState == 4) { // DONE
    if (xhr.status == 200) { // OK
      alert(xhr.responseText);
    } else {
      alert("status = " + xhr.status);
    } 
  }
}
xhr.open("POST", "hoge.cgi");
xhr.setRequestHeader("Content-Type" , "application/x-www-form-urlencoded");
xhr.send("a=b&c=d");

クロスドメイン[編集]

基本的には、XMLHttpRequestは同一ドメインとしか通信ができないが、XMLHttpRequest Level 2には、異なるドメインと通信する機能が追加になっており、Firefox 3.5以降、Google Chrome、Safari 4以降で利用可能である。また、Internet Explorer 8には、非標準の XDomainRequest があり、似たようなことが可能である。Opera は10.7現在、未実装。

クロスドメインを認めるには、サーバー側のHTTPレスポンスヘッダーに追加が必要であり、例えば、Access-Control-Allow-Origin: *と書くと全てのドメインからのアクセスが許可される。Access-Control-Allow-Origin は Internet Explorer を含め全てのクロスドメイン対応ブラウザで使える。W3Cの仕様は、Cross-Origin Resource Sharing にて規定されている。

また、Firefox では POST などで、text/plain など以外の Content-Type をクロスドメインで送信する場合、OPTIONS を使いプレフライトが行われる[5]

ストリーミング[編集]

readyState が 3 (LOADING) の状態で、基本的には、受信途中の通信内容を取ることができるので、そのことを使うと、受信ストリーミングが使用できる。ただし、各ブラウザで以下の制限事項がある[6]

  1. Internet ExplorerのXMLHttpRequestはreadyStateが3の状態では、内容がとれなく、Internet Explorer 8用のXDomainRequestを使用する必要があり、加えて、最初に2KBのダミーデータをサーバーから送る必要がある。Internet Explorer 7 以前では、ストリーミングは使えない。
  2. Google Chrome はバージョン6現在、readyStateが3の状態に移行するために、Content-Type: application/octet-stream とするか、1024バイト以上のデータをサーバーから送る必要がある[7]
  3. Opera 以外のブラウザでは、ブラウザ側でデータを受け取るたびに onreadystatechange が発生するが、Opera 11.0 では発生しないので、定期的にresponseTextの内容を見に行く必要がある。

ロングポーリング[編集]

HTTPの接続を張りっぱなしにしておいて、サーバーから情報を送りたいときに初めてレスポンスを返すことをロングポーリングと呼ぶ。Cometの実装に使われる。利用時に以下の注意点がある。

  1. ブラウザのHTTP接続のタイムアウト(30秒など)があるため、接続が切れたら、接続し直すロジックが必要である。
  2. サーバー当たりの同時接続数が、初期設定では、Internet Explorer 8以降や Internet Explorer 以外の主要ブラウザでは6[8]、Internet Explorer 7以前では2に制限されているため、複数のロングポーリングをこの制限まで同時に行うと、新たにサーバーに接続できなくなる。ダイアルアップ接続の場合、Internet Explorer 8でも同時接続数は2に制限されている。
  3. HTTPの接続が終了するまでサーバーが終了できなかったり、接続ごとにスレッドを作成し、同時接続数が多いとそれがメモリなどのリソースを大量に消費するなどの問題があるため、ロングポーリングに対応したサーバー側の実装方法が必要である。例えばJavaの場合は、Jettyならば独自のContinuationクラス、Apache Tomcatならば独自のCometProcessorクラスなど、Servlet 3.0ならばHTTPServletRequestにstartAsync()が用意されていて、それらのロングポーリング用のAPIを活用することが望ましい。

なおこれらの問題を根本的に解決することを目的として、現在IETF・W3C他では代替プロトコルとしてWebSocketの標準化作業を進めている。

脚注[編集]

[ヘルプ]
  1. ^ "Outlook Web Access - A catalyst for web evolution" You Had Me At EHLO..., Jim Van Eaton, 2005年6月21日
  2. ^ "Dynamic HTMLとXML:XMLHttpRequestオブジェクト" Apple Developer Connection, Apple, 2005年6月24日
  3. ^ "IE7 - XMLHttpRequest の標準サポート", ウィンドウズ開発統括部, 及川卓也, 2006年3月9日
  4. ^ Adam Wiener (2006年10月23日). “Using the right version of MSXML in Internet Explorer” (英語). Microsoft XML Team's WebLog. 2010年7月26日閲覧。
  5. ^ HTTP access control - MDC Doc Center
  6. ^ COMET Streaming in Internet Explorer - EricLaw's IEInternals - Site Home - MSDN Blogs
  7. ^ Issue 2016 - chromium - Chrome stalls XHRs in order to sniff mime-type - Project Hosting on Google Code
  8. ^ Network - Browserscope

関連項目[編集]

外部リンク[編集]

仕様[編集]

ブラウザ側の解説[編集]