XMLHttpRequest
XMLHttpRequest (XHR) は、JavaScriptなどのウェブブラウザ搭載のスクリプト言語でサーバとのHTTP通信を行うための、組み込みオブジェクト(API)である。
すでに読み込んだページからさらにHTTPリクエストを発することができ、ページ遷移することなしにデータを送受信できるAjaxの基幹技術である。
XMLHttpRequestを利用したWebアプリケーションは非常に多く存在し、例として、Google マップ、Facebookなどが挙げられる。
Contents
歴史
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]。
ウェブブラウザで実装されているデファクトスタンダードとなったことから、W3Cで仕様の標準化が進められ、XMLHttpRequest Level 1およびXMLHttpRequest Level 2の策定が始まった。その後、2014年11月18日に Level 2 が廃止され、Level 1 に統合された。また、今後の仕様策定は WHATWG で議論することになった[4]。
それ以降、WHATWGのXMLHttpRequest Living Standardが仕様として扱われている。
オブジェクトの構成
以下のAPIは、全ての主要なブラウザの最新版ではいずれも実装されている。
- メソッド
- abort
- getAllResponseHeaders
- getResponseHeader
- open
- overrideMimeType
- send
- setRequestHeader
- イベントハンドラ
- onloadstart
- onprogress
- onabort
- onerror
- onload
- ontimeout
- onloadend
- onreadystatechange
- プロパティ
- readyState
- 0 = UNSENT
- 1 = OPENED
- 2 = HEADERS_RECEIVED
- 3 = LOADING
- 4 = DONE
- response
- responseText
- responseType
- responseXML
- status
- statusText
- timeout
- upload
- withCredentials
- readyState
利用法
オブジェクトの作成
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を推奨している[5]。
また、見やすさと利便性を考慮してこのようなコードも使われる。 関数化により簡単に扱えるようにし、 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 があり、似たようなことが可能である。
クロスドメインを認めるには、サーバー側のHTTPレスポンスヘッダーに追加が必要であり、例えば、Access-Control-Allow-Origin: *
と書くと全てのドメインからのアクセスが許可される。Access-Control-Allow-Origin は Internet Explorer を含め全てのクロスドメイン対応ブラウザで使える。W3Cの仕様は、Cross-Origin Resource Sharing にて規定されている。
また、Firefox では POST などで、text/plain など以外の Content-Type をクロスドメインで送信する場合、OPTIONS を使いプレフライトが行われる[6]。
また、ブラウザの拡張機能などでは特別に制限を受けずに通信を行える機能が用意されている場合もある。
ストリーミング
readyState が 3 (LOADING) の状態で、基本的には、受信途中の通信内容を取ることができるので、そのことを使うと、受信ストリーミングが使用できる。ただし、各ブラウザで以下の制限事項がある[7]。
- Internet ExplorerのXMLHttpRequestはreadyStateが3の状態では、内容がとれなく、Internet Explorer 8用のXDomainRequestを使用する必要があり、加えて、最初に2KBのダミーデータをサーバーから送る必要がある。Internet Explorer 7 以前では、ストリーミングは使えない。
- Google Chrome はバージョン6現在、readyStateが3の状態に移行するために、Content-Type: application/octet-stream とするか、1024バイト以上のデータをサーバーから送る必要がある[8]。
- Opera 以外のブラウザでは、ブラウザ側でデータを受け取るたびに onreadystatechange が発生するが、Opera 11.0 では発生しないので、定期的にresponseTextの内容を見に行く必要がある。
脚注
- ↑ "Outlook Web Access - A catalyst for web evolution" You Had Me At EHLO..., Jim Van Eaton, 2005年6月21日
- ↑ "Dynamic HTMLとXML:XMLHttpRequestオブジェクト" Apple Developer Connection, Apple, 2005年6月24日
- ↑ "IE7 - XMLHttpRequest の標準サポート", ウィンドウズ開発統括部, 及川卓也, 2006年3月9日
- ↑ XMLHttpRequest Level 2 W3C Working Group Note
- ↑ Adam Wiener (2006年10月23日). “Using the right version of MSXML in Internet Explorer” (英語). Microsoft XML Team's WebLog. . 2010閲覧.
- ↑ “HTTP アクセス制御 (CORS) - HTTP”. Mozilla Developer Center. . 2017閲覧.
- ↑ COMET Streaming in Internet Explorer - EricLaw's IEInternals - Site Home - MSDN Blogs
- ↑ Issue 2016 - chromium - Chrome stalls XHRs in order to sniff mime-type - Project Hosting on Google Code
関連項目
外部リンク
仕様
- XMLHttpRequest Level 1 - W3C Working Draft (英語)
- XMLHttpRequest Level 2 - 廃止され Level 1 に統合された
- XMLHttpRequest Living Standard - WHATWG (英語)
- Cross-Origin Resource Sharing (英語)
- Progress Events 1.0 (英語)