Междоменный запрос (XDR)

Новые возможности Windows Internet Explorer 8

Используя междоменный запрос («XDR») в Internet Explorer 8, разработчики могут применять сценарии с объединением данных между сайтами. Этот запрос подобен объекту XMLHttpRequest, но отличается от него упрощенной моделью программирования; данный запрос называется XDomainRequest и является самым простым способом осуществления анонимных запросов к сторонним сайтам, поддерживающим XDR и готовым сделать свои данные доступными для нескольких доменов. Для простейших межсайтовых запросов достаточно трех строк кода. Благодаря этому сбор данных для общедоступных сайтов, таких как блоги и страницы социальных сетей, осуществляется просто, безопасно и быстро.

В этом разделе представлены следующие подразделы:

  • Основные сведения
  • Документация по API
  • Образец кода
  • См. также

Основные сведения

В веб-браузерах применяется политика безопасности, называемая политикой единого происхождения, которая не позволяет веб-страницам получать доступ к данным из других доменов. Разработчики веб-сайтов зачастую пытаются обойти эту политику следующим образом: сервер запрашивает содержимое с сайта другого сервера; при этом проверка на уровне браузера не фиксирует обращение к другому сайту. На следующей схеме показан этот процесс на типовом сайте при использовании Internet Explorer 7 и более ранних версий.

Dd573303.xdr1.gif

В Internet Explorer 8 веб-страницы могут просто запрашивать данные в других доменах с помощью нового объекта XDomainRequest вместо перенаправления запроса с одного сервера на другой. На следующей схеме показан междоменный запрос в Internet Explorer 8.

Dd573303.xdr2.gif

Для междоменных запросов требуется взаимный доступ между веб-страницей и сервером. Можно создать междоменный запрос на веб-странице, создав объект XDomainRequest из объекта window и открыв подключение к определенному домену. Браузер запросит данные с сервера этого домена, отправив заголовок Origin с указанным значением происхождения. Подключение будет установлено только в том случае, если сервер в ответ выдаст заголовок Access-Control-Allow-Origin для адреса * или для точного URL-адреса запрашивающей страницы. Такое поведение описывается в черновике структуры междоменного обмена данным на стороне клиентов, разработанной рабочей группой веб-приложений консорциума W3C; с этой структурой интегрируется объект XDomainRequest.

Например, 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 нужно скопировать эту страницу на веб-сервер, находящийся в другом домене. Также можно включить на компьютере службы 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 отправляет запрос get по указанному URL-адресу.
  • Кнопка 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

См. также