Firefox3のクロスサイトXMLHttpRequestの仕様

補足 2008.3.28

Cross Site XMLHttpRequest (XHR) Removed From Firefox 3 | Robert Accettura’s Fun With Wordageによると、最近XMLHttpRequestの仕様ドラフトに変更があり、Firefox3のリリース(今のところ6月の予定だとどこかで読みました)には実装が間に合わなそうなので、Firefox3の初期バージョンにはCross Site XMLHttpRequestは載らないことになったそうです。

Firefox3ではドメインが異なっていてもXMLHttpRequestでリクエストが出せるのをmal_blue@tumblrで知りました。

すごいじゃーんというわけでJohn Resig - Cross-Site XMLHttpRequestに書かれている使いかたを参考にちょっといじってみました。今までのXMLHttpRequestは異なるドメインのURLを引数に渡すとそもそもHTTPのリクエスト自体送られませんでしたが、Firefox3からは異なるドメインのURLを渡してもHTTPのリクエストは送信されるように仕様がかわっています。リクエストは無条件で送信されますが、帰ってきたレスポンスに、サーバ側がクロスドメインのXMLHttpRequestを許可していることが明示されているときのみ、ブラウザがレスポンスの中身をXMLHttpRequestの結果としてスクリプトに返してくれる実装になっています。サーバ側が許可していることを明示していないときはエラーになります。

サーバがクロスドメインの呼び出しを許可する方法はクロスドメインのXMLHttpRequestを許可する方法は二通りあって、Cross-Site XMLHttpRequest - MDCにまとめられていています。

HTTPのレスポンスヘッダを使う

ひとつめはサーバがブラウザに返すレスポンスヘッダにAccess-Controlというヘッダをつけることです。返すデータがなんであっても、レスポンスに
Access-Control: allow <*>
というヘッダがついていれば、このサーバにはXMLHttpRequestを使ってどのドメインにあるページからでも通信することができます。 特定のドメインからだけアクセスできるようにしたい場合というのはあんまりない気がしますが、下記のようにしてドメインを指定することもできます。
Access-Control: allow <*.tumblr.com>

ドメインを指定することで、指定したドメイン以外にある悪意あるコードにはリクエスト自体は送られるもののクライアントがレスポンスヘッダのAccess-Controlを見て、意図していないドメインからのリクエストであればエラー扱いにしてくれます。今まではクロスドメインのリクエスト自体が送られなかったのに、Firefox3ではどんなときでもリクエスト自体は送られるので感覚的になんか怖いのですが、悪意あるページがデータを読み出そうとするページにリクエストを送ること自体は以前からscriptタグやiframeタグを使ってもできるのでクロスドメインXMLHttpRequest固有のものではありません。Firefox3の仕様変更は、他の方法を使えば前からできたことがXMLHttpRequestでもできるようになっただけです。情報が漏洩してしまうかどうかは、悪意あるページがそうして送ったリクエストの中身がスクリプトから読み出せるかどうかの部分にあります。

XMLのプロセッシングインストラクションを使う

ふたつめはXMLのプロセッシングインストラクションに <?access-control ?> を入れる方法です。HTTPのレスポンスヘッダに入れる方法はサーバを細かく操作できる場合に限られますが、この方法は返すデータの中に文字列を入れるだけなので、サーバ側のコーディングになんらかの制約がある場合にも利用できます。返すデータがXMLであればというのがちょっとつらくはありますけれども。 Cross-Site XMLHttpRequest - MDCにある例そのままですが
 <?xml version="1.0" encoding="UTF-8"?>
 <?access-control allow="ejohn.org"?>
 <simple><name>John Resig</name></simple>
このようにXML宣言のあと、HTTPのレスポンスヘッダに入れる場合と同様にアクセスを許可するリクエスト元のドメインを記述します。

実習

http://labs.gmo.jp/blog/ku/XSXHR.phpにHTTPレスポンスヘッダでtumblr上にあるページからであればクロスドメインのXMLHttpRequestを許可するコードを置きました。
<?php
header('Access-Control: allow <*.tumblr.com>');
print strftime("%T", time());
?>
これをいろんなページから呼び出してみましょう。
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://labs.gmo.jp/blog/ku/XSXHR.php", false);
xhr.send(null);
console.log( xhr.responseText );

www.tumblr.comから

http://labs.gmo.jp/blog/ku/XSXHR.phpのレスポンスヘッダに
Access-Control: allow <*.tumblr.com>
が含まれているのでwww.tumblr.comからはXMLHttpRequestを使うことができます。
XHR from www.tumblr.com

yahoo.co.jpから

www.yahoo.co.jpはサーバの返すAccess-Controlヘッダで許可されていないのでエラーになります。
XHR from www.yahoo.co.jp

labs.gmo.jpから

最後にlabs.gmo.jpから。Access-Controlヘッダで許可されていないのにエラーにならないですが、それはXMLHttpRequest先が同じドメインのhttp://labs.gmo.jp/blog/ku/XSXHR.phpだからです。同じドメインに送れるのはふつうにできるのを忘れていました。同じドメインのときは以前と同様で無条件で許可されていて、異なるドメインのときはAccess-Controlで許可されていれば読み出せるようになっています。
XHR from labs.gmo.jp

まとめ

というわけでFirefox3ではXMLHttpRequestはクロスドメインでリクエストを送られるようになっています。 リクエスト自体は無条件で送ることが可能です。この無条件でクロスドメインのリクエストを送れることは以前からscriptタグ等を使って可能であり、クロスサイトXMLHttpRequestに固有の特徴ではありません。クロスサイトの通信でよく利用されるJSONPには、特定のドメインからのアクセスに限って許可するといった制御ができないのに対して、クロスサイトXMLHttpRequestではレスポンスからクライアントのスクリプトがデータを読み出せるかどうかをサーバがコントロールできる仕様になっています。

クライアント側から見た場合、いままでJSONP等の動的にDOM要素を生成するハックでクロスドメインのリクエストを出すしかなかったものが、DOM要素の生成、操作という大きなオーバーヘッドを伴うハックなしにできるようになったところがクロスサイトXMLHttpRequestの利点です。サーバ側から見た場合、いままでアクセスのコントロールがまったくできない状態だったのがAccess-Controlヘッダで制御が可能になったという利点があります。


実際のところはサポートしているブラウザがFirefox3しかないので、現状では使える場面がないといっていいと思いますが、このクロスサイトXMLHttpRequestの仕様自体はW3CにAccess Control for Cross-site Requestsとして提案されているので将来的に他のブラウザでもサポートされることがあるかもしれません。

tags

  • Firefox
  • javascript
  • 「Firefox3のクロスサイトXMLHttpRequestの仕様」のはてなブックマーク数
  • 「Firefox3のクロスサイトXMLHttpRequestの仕様」deliciousブックマーク数
  • 「Firefox3のクロスサイトXMLHttpRequestの仕様」をはてなブックマークに追加
  • save "Firefox3のクロスサイトXMLHttpRequestの仕様" to del.icio.us
  • 「Firefox3のクロスサイトXMLHttpRequestの仕様」をリアルタイムブログ検索
  • permalink
  • Firefox3でC++実装のXPCOMコンポーネントを作る
  • Lilyで視覚的にHTTPDサーバを作る

comments

TypeKey Enabled
スタイル用のHTMLタグが使えます。
*required

trackbacks

トラックバック元エントリにこのエントリへのリンクがない場合はトラックバックを受け付けません。

http://labs.gmo.jp/mt/mt-tb.cgi/190
©2010 Kentaro Kumagai, GMO Internet Labs., GMO Internet, inc.
bits and bytes
2008 .01. 17 14:11

tagcloud

  • API1
  • C/C++2
  • E4X1
  • FUSE2
  • Firefox23
  • HTML4
  • IE1
  • MySQL1
  • OSX4
  • Opera2
  • PHP4
  • UI2
  • XML1
  • XPCOM4
  • XPath3
  • apache2
  • binary2
  • book1
  • data12
  • debug5
  • design1
  • experiments3
  • extension13
  • google gears1
  • google maps API1
  • greasemonkey4
  • httpd5
  • javascript19
  • linux1
  • logging2
  • mobile3
  • perl4
  • tips5
  • tool11
  • vim2
  • visualization2
  • widget1
  • wii2
  • windows7
  • サービス6
  • 和訳1

Archives

  • 2008.04 (1)
  • 2008.03 (4)
  • 2008.02 (6)
  • 2008.01 (3)
  • 2007.12 (4)
  • 2007.11 (5)
  • 2007.10 (4)
  • 2007.09 (4)
  • 2007.08 (4)
  • 2007.07 (8)
  • 2007.06 (7)
  • 2007.05 (4)
  • 2007.04 (5)
  • 2007.03 (6)
  • 2007.02 (4)
  • 2007.01 (6)

about

  • bits and bytesのXML
  • 「bits and bytes」のCreative Commons
  • Powered by Movable Type
  • イベントと地図 - モグ
  • Use ecto to blog!
  • bits and bytesのはてなブックマーク数
  • bits and bytesをMy Yahoo!に追加
  • Subscribe with Bloglines