跨域请求 (XDR) 简介

Windows Internet Explorer 8 的新增功能

通过使用 Internet Explorer 8 中的跨域请求(缩写为“XDR”),开发人员可以创建跨网站数据聚合方案。 这个名为 XDomainRequest 的请求与 XMLHttpRequest 对象类似,但编程模型更加简单,它可以提供一种最简单的方式来向支持 XDR 的第三方站点发出匿名请求,并选择使这些站点的数据可跨域使用。 只需三行代码即可生成基本的跨站点请求。 这将确保针对公共站点(例如,博客或其他社交网络应用程序)的数据聚合简单、安全和快速。

本主题包含以下各部分。

  • 背景
  • API 文档
  • 代码示例
  • 相关主题

背景

Web 浏览器具有一个称为相同站点源策略的安全策略,此策略可阻止网页访问另一个域中的数据。 网站通常会让其服务器在后端请求其他站点服务器中的内容,由此避开浏览器中的检查,从而绕开此策略。 下图演示了这一过程(针对典型的混合站点和 Internet Explorer 7 及更早版本)。

Dd573303.xdr1.gif

在 Internet Explorer 8 中,通过使用新的 XDomainRequest 对象,网页可以直接在浏览器中生成跨域数据请求,而不必使用服务器到服务器的请求。 下图演示了 Internet Explorer 8 中的跨域请求。

Dd573303.xdr2.gif

跨域请求需要经过网页和服务器的相互同意。 通过利用 window 对象创建 XDomainRequest 对象,并打开到特定域的连接,可以在网页中启动一个跨域请求。 浏览器将通过发送带有源值的 Origin 标头,从特定域的服务器中请求数据。 如果服务器响应的 Access-Control-Allow-Origin 标头为 * 或请求页面的确切 URL,则浏览器将仅仅完成连接。 此行为是万维网联盟 (W3C) 的 Web 应用程序工作组制定的、针对与 XDomainRequest 对象集成的客户端跨域通信的草稿框架的一部分。

例如,服务器的 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 具有两个组件: 一个客户端,用于向某个 URL 跨域请求数据;一个服务器端,用于通过 Access-Control-Allow-Origin 标头(值为 * 或请求页面的确切 URL)以及相关数据提供响应,Internet Explorer 在执行安全检查后,会将这些数据提供给请求域使用。

此示例页采用一个 URL 并执行 get 请求。 如果您选择“Read”(读取)按钮,则该按钮将调用一个方法以输出响应数据。 下面的第一个代码示例为请求页。

注意  若要正确演示 XDR,应将此页面复制到不同域上的 Web 服务器中。 也可以在您的计算机上启用 Microsoft Internet Information Services (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”(显示)按钮,试一试。 请注意以下两个字段和三个按钮:

  • “URL”字段预设了一个 URL,页面将向其发送 get 请求。 该文件的 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”(读取)按钮用于读取响应文本,并将其写入到页面中,然后读取并显示内容类型和长度。

第二个代码示例为请求页中引用的目标页。 在本例中,目标页中包含一个电影数据的列表。

<% 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

相关主题