跨域请求 (XDR) 简介
通过使用 Internet Explorer 8 中的跨域请求(缩写为“XDR”),开发人员可以创建跨网站数据聚合方案。 这个名为 XDomainRequest 的请求与 XMLHttpRequest 对象类似,但编程模型更加简单,它可以提供一种最简单的方式来向支持 XDR 的第三方站点发出匿名请求,并选择使这些站点的数据可跨域使用。 只需三行代码即可生成基本的跨站点请求。 这将确保针对公共站点(例如,博客或其他社交网络应用程序)的数据聚合简单、安全和快速。
本主题包含以下各部分。
- 背景
- API 文档
- 代码示例
- 相关主题
背景
Web 浏览器具有一个称为相同站点源策略的安全策略,此策略可阻止网页访问另一个域中的数据。 网站通常会让其服务器在后端请求其他站点服务器中的内容,由此避开浏览器中的检查,从而绕开此策略。 下图演示了这一过程(针对典型的混合站点和 Internet Explorer 7 及更早版本)。
在 Internet Explorer 8 中,通过使用新的 XDomainRequest 对象,网页可以直接在浏览器中生成跨域数据请求,而不必使用服务器到服务器的请求。 下图演示了 Internet Explorer 8 中的跨域请求。
跨域请求需要经过网页和服务器的相互同意。 通过利用 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"> <input onclick="req_abort()" type="button" value="Abort"> <input onclick="read_data()" type="button" value="Read"></p> </form> <div id="text_response"> </div> </div> </body> </html>
单击“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