ドメイン間要求 (XDR) の概要

開発者は、Internet Explorer 8 のドメイン間要求 ("XDR") を使用して、サイト間のデータ集計シナリオを作成できます。 XDomainRequest と呼ばれるこの要求は、 XMLHttpRequest オブジェクトと似ていますがプログラミング モデルがより簡単になっており、XDR をサポートしてドメイン間でデータを利用できるようになったサード パーティのサイトに対して、匿名の要求を作成する最も簡単な方法です。 3 行のコードで基本的なクロスサイト要求を作成します。 これにより、ブログなどのパブリック サイトやその他のソーシャル ネットワーク アプリケーションのデータ収集が高速で安全かつ簡単に行われます。

このトピックは、次の各セクションで構成されています。

  • 背景
  • API ドキュメント
  • コード サンプル
  • 関連トピック

背景

Web ブラウザーには、同じサイト生成元ポリシーと呼ばれるセキュリティ ポリシーがあり、Web ページが他のドメインのデータにアクセスできないようになっています。 多くの場合、Web サイトは、他のサイトのサーバーに対してコンテンツを要求するようにサーバーをバックエンドで設定し、ブラウザーでのチェックを回避することにより、このポリシーに対処します。 次の図は、一般的なマッシュアップ サイトと Internet Explorer 7 以前でのこのプロセスを示しています。

Dd573303.xdr1.gif

Internet Explorer 8 では、Web ページは、サーバー間要求の代わりに新しい XDomainRequest オブジェクトを使用して、ブラウザー内のドメイン間要求を簡単に作成できます。 次の図は、Internet Explorer 8 のドメイン間要求を示しています。

Dd573303.xdr2.gif

ドメイン間要求には、Web ページとサーバー双方の合意が必要です。 window オブジェクトから XDomainRequest オブジェクトを作成し、特定のドメインへの接続を開くことにより、Web ページでドメイン間要求を開始できます。 ブラウザーは、要求元の値を持った Origin ヘッダーを送信し、ドメインのサーバーに対してデータを要求します。 サーバーが * または要求元ページの正確な URL を持つ Access-Control-Allow-Origin ヘッダーを返した場合に限り、ブラウザーは接続を確立します。 この動作は、XDomainRequest オブジェクトが統合されたクライアント側のドメイン間通信に関する、World Wide Web コンソーシアム (W3C) の Web Application Working Group のドラフトの枠組みの一部です。

たとえば、サーバーの Active Server Pages (ASP) ページには、次の応答ヘッダーが含まれる場合があります。

<% Response.AddHeader("Access-Control-Allow-Origin","*") %>

セキュリティに関するメモ セキュリティ警告 : ユーザー データを保護するために、ドメイン間要求は匿名です。つまり、サーバーはデータを要求している相手を簡単に特定できません。 その結果、機密性が高くない、または個人が特定されないドメイン間データのみで、要求と応答を実行できます。

API ドキュメント

次の JavaScript コードでは、XDomainRequest オブジェクト、そのイベント、プロパティ、およびメソッドについて説明します。 XDomainRequest リファレンス ページには、ここで示されているより詳細な情報が記載されています。

// Creates a new XDR object.
xdr = new XDomainRequest();  

// Indicates there is an error and the request cannot be completed. 
xdr.onerror = alert_error;
                        
// The request has reached its timeout. 
xdr.ontimeout = alert_timeout;
                        
// The object has started returning data.
xdr.onprogress = alert_progress;
                        
// The object is complete. 
xdr.onload = alert_loaded;

// Sets the timeout interval.
xdr.timeout = timeout;

// Gets the content-type header in the request.
var content_type = xdr.contentType;

// Gets the body of the response.
var response = xdr.responseText;
                        
// Creates a connection with a domain's server. 
xdr.open("get", url);
 
// Transmits a data string to the server. 
xdr.send();

// Terminates a pending send.
xdr.abort();

コード サンプル

XDR には、次の 2 つのコンポーネントがあります。 ドメイン間 URL に対してデータの要求を作成するクライアント側のコンポーネントと、* または要求元ページの正確な URL を持つ Access-Control-Allow-Origin ヘッダーおよびデータで応答するサーバー側のコンポーネントです。Internet Explorer は、セキュリティ チェック後に、このデータを要求元ドメインで利用できるようにします。

このサンプル ページでは、URL を取得し、 get 要求を実行します。 [Read] ボタンは、応答データを出力するように選択した場合は、それを実行するメソッドを呼び出します。 次の最初のコード サンプルは、要求元ページです。

メモ : XDR を適切に実行するには、このページを別のドメインの Web サーバーにコピーする必要があります。 またコンピューター上で Microsoft インターネット インフォメーション サービス (IIS) を有効にし、C:\inetpub\wwwroot からローカルにホストすることもできます。 IIS のインストールの詳細については、[スタート] メニューの [ヘルプとサポート] で "IIS" を検索してください。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>

<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<title>Internet Explorer 8 - Cross-domain Request Code Sample</title>
<script type="text/javascript">
    var xdr;

    function read_data()
    {
        var output = document.getElementById('text_response');
        if(output)
        {
        // To view the responseText on the page, click the Read button. 
            output.innerText = xdr.responseText;
        }

        // The Read button also displays the content type and length of 
        // response in alerts.  
        alert("Content-type: " + xdr.contentType);
        alert("Length: " + xdr.responseText.length);
    }

    function alert_error()
    {
        alert("XDR onerror");
    }

    function alert_timeout()
    {
        alert("XDR ontimeout");
    }

    function alert_loaded()
    {
        alert("XDR onload");
        alert("Got: " + xdr.responseText);
    }

    function alert_progress()
    {
        alert("XDR onprogress");
        alert("Got: " + xdr.responseText);
    }

    function req_abort()
    {
        if(xdr)
        {
            xdr.abort(); // Abort XDR if the Stop button is pressed. 
        }
    }

    function req_init()
    {
        var url = 
        document.getElementById('input_url').value;
        var timeout = 
            document.getElementById('input_timeout').value;
        if (window.XDomainRequest) // Check whether the browser supports XDR. 
        {
            xdr = new XDomainRequest(); // Create a new XDR object.
            if (xdr)
            {
                // There is an error and the request cannot be completed. 
                // For example, the network is not available.
                xdr.onerror     = alert_error;
                        
                // This event is raised when the request reaches its timeout. 
                xdr.ontimeout   = alert_timeout;
                        
                // When the object starts returning data, the onprogress event 
                // is raised and the data can be retrieved by using responseText.
                xdr.onprogress  = alert_progress;
                       
                // When the object is complete, the onload event is raised and 
                // the responseText ensures the data is available. 
                xdr.onload      = alert_loaded;

                xdr.timeout     = timeout;
                        
                // The URL is preset in the text area. This is passed in the 
                // open call with a get request.
                xdr.open("get", url);
                        
                // The request is then sent to the server.  
                xdr.send();
            }
            else
            {
                alert('Failed to create new XDR object.');
            }
        }
        else
        {
            alert('XDR does not exist.');
        }
    }

</script>
</head>

<body>

<div class="body">
	<h1>Internet Explorer 8 - Cross-domain Request Demo</h1>
	<form action="">
		<!-- Assign URL and timeout values from their text boxes to variables. -->
		<p>URL:	<input id="input_url" type="text" 
		value="http://samples.msdn.microsoft.com/workshop/samples/author/dhtml/Ajax/xdomain.response.movies.aspx"
		style="width: 700px"></p>
		
		<p>Timeout: <input id="input_timeout" type="text" value="10000"></p>
		
		<p><input onclick="req_init()" type="button" value="Get">&nbsp;&nbsp;&nbsp;
		<input onclick="req_abort()" type="button" value="Abort">&nbsp;&nbsp;&nbsp;
		<input onclick="read_data()" type="button" value="Read"></p>
	</form>
	<div id="text_response">
	</div>
</div>

</body>

</html>

Show Me

[Show Me] ボタンをクリックして、結果を確認します。 2 つのフィールドと 3 つのボタンに注目してください。

  • URL フィールドには、ページが get 要求を送信する URL が事前設定されています。 ファイルの URL は、http://samples.msdn.microsoft.com/workshop/samples/author/dhtml/Ajax/xdomain.response.movies.aspx です。
  • Timeout フィールドには、10,000 ミリ秒 (10 秒) のタイムアウト値が事前設定されています。
  • [Get] ボタンは、指定された URL に get 要求を送信します。
  • [Stop] ボタンは、get 要求を停止します。
  • [Read] ボタンは応答テキストを読み取り、それをページに書き込んでから、コンテンツのタイプと長さの両方を読み取って表示します。

2 番目のコード サンプルは、要求元ページで参照されるターゲット ページです。 このケースでは、ターゲット ページにはムービー データの一覧が含まれています。

<% Response.AddHeader("Access-Control-Allow-Origin","*") %>
movieID|movieName|actor|genre
1|Fistful of Dollars|Clint Eastwood
2|Mission Impossible|Tom Cruise|Action
3|Enforcer|Clint Eastwood|Love Story
4|Gauntlet|Clint Eastwood
5|LawnMower Man|John Curtis|Drama
6|The Shining|Jack Nicholson|Drama
7|Dirty Harry|Clint Eastwood|Make my day
8|Two mules for Sister Sarah|Clint Eastwood
9|Hard to Kill|Stephen Segal|Action
10|Top Gun|Tom Cruise|High Intense Action

関連トピック