Междоменный запрос (XDR)
Используя междоменный запрос («XDR») в Internet Explorer 8, разработчики могут применять сценарии с объединением данных между сайтами. Этот запрос подобен объекту XMLHttpRequest, но отличается от него упрощенной моделью программирования; данный запрос называется XDomainRequest и является самым простым способом осуществления анонимных запросов к сторонним сайтам, поддерживающим XDR и готовым сделать свои данные доступными для нескольких доменов. Для простейших межсайтовых запросов достаточно трех строк кода. Благодаря этому сбор данных для общедоступных сайтов, таких как блоги и страницы социальных сетей, осуществляется просто, безопасно и быстро.
В этом разделе представлены следующие подразделы:
- Основные сведения
- Документация по API
- Образец кода
- См. также
Основные сведения
В веб-браузерах применяется политика безопасности, называемая политикой единого происхождения, которая не позволяет веб-страницам получать доступ к данным из других доменов. Разработчики веб-сайтов зачастую пытаются обойти эту политику следующим образом: сервер запрашивает содержимое с сайта другого сервера; при этом проверка на уровне браузера не фиксирует обращение к другому сайту. На следующей схеме показан этот процесс на типовом сайте при использовании Internet Explorer 7 и более ранних версий.
В Internet Explorer 8 веб-страницы могут просто запрашивать данные в других доменах с помощью нового объекта XDomainRequest вместо перенаправления запроса с одного сервера на другой. На следующей схеме показан междоменный запрос в Internet Explorer 8.
Для междоменных запросов требуется взаимный доступ между веб-страницей и сервером. Можно создать междоменный запрос на веб-странице, создав объект 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"> <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 отправляет запрос 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