Xmlhttprequest

Example Explained

1: Create an array of objects.

Use an array literal to declare an array of
objects.

Give each object two properties:
display and url.

Name the array myArray:

myArray

var myArray = [
{
«display»: «JavaScript Tutorial»,
«url»: «https://www.w3schools.com/js/default.asp»
},
{
«display»: «HTML Tutorial»,
«url»: «https://www.w3schools.com/html/default.asp»
},
{
«display»: «CSS Tutorial»,
«url»: «https://www.w3schools.com/css/default.asp»
}
]

2: Create a JavaScript function to display the array. 

Create a function myFunction() that loops the array objects,
and display the content as HTML links:

myFunction()

function myFunction(arr) {
    var out = «»;    var i;
    for(i = 0; i < arr.length; i++) {
        out += ‘<a href=»‘ + arr.url + ‘»>’ + arr.display + ‘</a><br>’;
    }
    document.getElementById(«id01»).innerHTML = out;
}

Call myFunction() with myArray as argument:

myFunction(myArray);

3: Create a text file

Put the array literal in a file named myTutorials.txt:

myTutorials.txt

[
{
«display»: «JavaScript Tutorial»,
«url»: «https://www.w3schools.com/js/default.asp»
},
{
«display»: «HTML Tutorial»,
«url»: «https://www.w3schools.com/html/default.asp»
},
{
«display»: «CSS Tutorial»,
«url»: «https://www.w3schools.com/css/default.asp»
}
]

4: Read the text file with an XMLHttpRequest

Write an XMLHttpRequest to read the text file, and use
myFunction() to display the
array:

XMLHttpRequest

var xmlhttp = new XMLHttpRequest();var url = «myTutorials.txt»;
xmlhttp.onreadystatechange = function() {if (this.readyState == 4 && this.status == 200) {    var myArr = JSON.parse(this.responseText);   
myFunction(myArr);    }};xmlhttp.open(«GET»,
url, true);xmlhttp.send();

❮ Previous
Next ❯

Стандарты идентификатора объекта

Поскольку стандарт W3C для объекта XMLHttpRequest Javascript post по-прежнему является предварительным вариантом, пользовательские агенты могут не соблюдать все функции определения, а любое из последующих действий может быть изменено. Экстремальный уход следует учитывать при написании сценария с объектом XMLHttpRequest для нескольких пользовательских агентов.

В HTTP и HTTPS запросы объекта XMLHttpRequest инициализируются открытым способом. Он вызывается до фактической отправки запроса для проверки. Этот метод не гарантирует, что URL-адрес существует, а информация пользователя верна. Он может принимать до пяти параметров, но для инициализации запроса требует только два. Первым параметром является текстовая строка. Представляем методы запросов, которые должны поддерживаться соответствующим агентом пользователя, определенным проектом W3C для XMLHttpRequest Javascript. Примеры:

  1. GET поддерживается Internet Explorer 7, Mozilla.
  2. POST поддерживается IE7, Mozilla.
  3. HEAD поддерживается IE7.

Методы запроса не ограничиваются перечисленными выше. В проекте W3C говорится, что браузер может поддерживать их по своему усмотрению.

Второй параметр — это еще одна текстовая строка, которая указывает URL-адрес HTTP-запроса.

Третий параметр — это логическое значение, указывающее, будет ли запрос асинхронным. Он не является обязательным по проекту W3C. Его значение по умолчанию должно считаться истинным с помощью соответствующего пользовательского агента W3C.

Асинхронный запрос «истина» не будет ждать ответа сервера, прежде чем продолжить выполнение текущего скрипта. Вместо этого он вызовет прослушивателя событий onreadystatechange объекта XMLHttpRequest Javascript post на разных этапах запроса.

Четвертый и пятый параметры — это имя пользователя и пароль. Эти параметры могут быть предоставлены для аутентификации и авторизации, если это требуется сервером.

基本

XMLHttpRequest には2つの操作モードがあります: 同期と非同期です。

先に、ほとんどのケースで使われる非同期を見ていきましょう。

リクエストをするためには、次の3ステップが必要です:

  1. を作成します:

  2. 初期化をします:

    このメソッドは通常 のすぐ後で呼ばれ、リクエストのメインのパラメータを指定します。:

    • – HTTPメソッド. たいてい か です.
    • – リクエストURL。文字列で、URL オブジェクトもOKです。
    • – 明示的に が指定されている場合、リクエストは同期になります。これについては後ほど説明します。
    • , – ベーシック HTTP 認証のユーザとパスワードです(必要に応じて).

    呼び出しに注意してください。その名前とは対照的に、接続をオープンするわけではありません。リクエストを設定するだけで、ネットワーク処理は 呼び出しでのみ始まります。

  3. それを送ります

    このメソッドは接続をオープンし、リクエストをサーバに送信します。オプションの パラメータにはリクエストボディが含まれます。

    のようないくつかのリクエストメソッドは body を持ちません。また などはデータをサーバに送信するのに を使います。後ほど例を見ていきます。

  4. 応答に対するイベントをリッスンします

    これら3つがもっとも広く使われています:

    • – 結果が準備できたとき。404 のような HTTP エラーを含みます。
    • – リクエストが送信できなかったとき e.g. ネットワークダウン or URL不正
    • – ダウンロード中に定期的にトリガーされ、ダウンロードされた量が確認できます。

これは完全な例です。下のコードはサーバから のURLをロードし、進行状況を表示します。:

サーバーが応答すると、リクエストオブジェクトの次のプロパティで結果を受け取ることができます。:

HTTPステータスコード(数値): , , など。HTTP 以外の失敗の場合は になります。

:HTTPステータスメッセージ(文字列): 通常, の場合は 、 の場合は 、 の場合は など。

(古いスクリプトはを使用する場合があります)
:サーバーのレスポンス。

対応するプロパティを使用してタイムアウトを指定することもできます。:

リクエストが指定時間内で成功しない場合はキャンセルされ、 イベントが発生します。

URL 検索パラメータ

のような URL パラメータを渡しつつ、適切なエンコーディングを保証するには、URL オブジェクトが使えます。:

Summary

Typical code of the GET-request with :

There are actually more events, the lists them (in the lifecycle order):

  • – the request has started.
  • – a data packet of the response has arrived, the whole response body at the moment is in .
  • – the request was canceled by the call .
  • – connection error has occurred, e.g. wrong domain name. Doesn’t happen for HTTP-errors like 404.
  • – the request has finished successfully.
  • – the request was canceled due to timeout (only happens if it was set).
  • – triggers after , , or .

The , , , and events are mutually exclusive. Only one of them may happen.

The most used events are load completion (), load failure (), or we can use a single handler and check the properties of the request object to see what happened.

We’ve already seen another event: . Historically, it appeared long ago, before the specification settled. Nowadays, there’s no need to use it, we can replace it with newer events, but it can often be found in older scripts.

If we need to track uploading specifically, then we should listen to same events on object.

Other signatures


  • a simple string instead of the options. In this case, a GET request will be made to that url.


  • the above may also be called with the standard set of options.

The module has convience functions attached that will make requests with the given method.
Each function is named after its method, with the exception of which is called for compatibility.

The method shorthands may be combined with the url-first form of for succinct and descriptive requests. For example,

xhr.post('/post-to-me',function(err,resp){console.log(resp.body)})

or

xhr.del('/delete-me',{ headers{ my'auth'}},function(err,resp){console.log(resp.statusCode);})

Контроль безопасности

Кросс-доменные запросы проходят специальный контроль безопасности, цель которого – не дать злым хакерам завоевать интернет.

Серьёзно. Разработчики стандарта предусмотрели все заслоны, чтобы «злой хакер» не смог, воспользовавшись новым стандартом, сделать что-то принципиально отличное от того, что и так мог раньше и, таким образом, «сломать» какой-нибудь сервер, работающий по-старому стандарту и не ожидающий ничего принципиально нового.

Давайте, на минуточку, вообразим, что появился стандарт, который даёт, без ограничений, возможность делать любой странице HTTP-запросы куда угодно, какие угодно.

Как сможет этим воспользоваться злой хакер?

Он сделает свой сайт, например и заманит туда посетителя (а может посетитель попадёт на «злонамеренную» страницу и по ошибке – не так важно). Когда посетитель зайдёт на , он автоматически запустит JS-скрипт на странице

Этот скрипт сделает HTTP-запрос на почтовый сервер, к примеру,. А ведь обычно HTTP-запросы идут с куками посетителя и другими авторизующими заголовками

Когда посетитель зайдёт на , он автоматически запустит JS-скрипт на странице. Этот скрипт сделает HTTP-запрос на почтовый сервер, к примеру, . А ведь обычно HTTP-запросы идут с куками посетителя и другими авторизующими заголовками.

Поэтому хакер сможет написать на код, который, сделав GET-запрос на , получит информацию из почтового ящика посетителя. Проанализирует её, сделает ещё пачку POST-запросов для отправки писем от имени посетителя. Затем настанет очередь онлайн-банка и так далее.

Спецификация CORS налагает специальные ограничения на запросы, которые призваны не допустить подобного апокалипсиса.

Запросы в ней делятся на два вида.

считаются запросы, если они удовлетворяют следующим двум условиям:

  1. : GET, POST или HEAD
  2. – только из списка:
  • со значением , или .

«Непростыми» считаются все остальные, например, запрос с методом или с заголовком не подходит под ограничения выше.

Принципиальная разница между ними заключается в том, что «простой» запрос можно сформировать и отправить на сервер и без XMLHttpRequest, например при помощи HTML-формы.

То есть, злой хакер на странице и до появления CORS мог отправить произвольный GET-запрос куда угодно. Например, если создать и добавить в документ элемент , то браузер сделает GET-запрос на этот URL.

Аналогично, злой хакер и ранее мог на своей странице объявить и, при помощи JavaScript, отправить HTML-форму с методом GET/POST и кодировкой . А значит, даже старый сервер наверняка предусматривает возможность таких атак и умеет от них защищаться.

А вот запросы с нестандартными заголовками или с методом таким образом не создать. Поэтому старый сервер может быть к ним не готов. Или, к примеру, он может полагать, что такие запросы веб-страница в принципе не умеет присылать, значит они пришли из привилегированного приложения, и дать им слишком много прав.

Поэтому при посылке «непростых» запросов нужно специальным образом спросить у сервера, согласен ли он в принципе на подобные кросс-доменные запросы или нет? И, если сервер не ответит, что согласен – значит, нет.

В спецификации CORS, как мы увидим далее, есть много деталей, но все они объединены единым принципом: новые возможности доступны только с явного согласия сервера (по умолчанию – нет).

Конструктор

Конструктор создаёт объект XMLHttpRequest. Он должен быть вызван перед обращением к любому методу класса.

Gecko/Firefox 16 добавляет нестандартные параметры в конструктор, для лучшего взаимодействия с режимом инкогнито, (смотри Bug 692677). Установка флага  в значение  создаёт сущность описанную в XMLHttpRequest спецификации, но не реализованную не в одном из браузеров (информация сентября 2012).

XMLHttpRequest (
  JSObject objParameters
);
Параметры (нестандартные)
Вы можете использовать два флага:

Boolean: Использование этого флага уберёт из запроса заголовки origin, и . Кроме этого, куки не будут отправлены в запросе, если только они не будут добавлены к запросу специально, через метод setRequestHeader.
Boolean: Если выставить этот флаг в значение  то это позволит делать cross-доменные запросы без необходимости получения специальных заголовков со стороны сервера (CORS). Для использования этого флага необходимо использовать дополнительный флаг , поскольку для отправки запроса на другой домен, нельзя использовать куки и креды пользователя. Этот флаг ; он не сработает с произвольно загруженными страницами.

4 ответа

Лучший ответ

HTTP это протокол. Частью этого протокола является концепция заголовков запросов. Когда происходит xhr, между клиентом и сервером происходит обмен текстом. Заголовки запроса являются частью текста, который клиент отправляет на сервер.

Это способ установить заголовки запроса. Аргументы, которые вы видите

1) настраиваемый заголовок (в данном случае Content-type ) 2) значение заголовка. (в этом случае x-www-form-urlencoded )

20

hvgotcodes
16 Янв 2012 в 16:02

Он устанавливает HTTP-заголовок Content-type для хранения данных в кодировке url, отправленных из формы.

JanL
16 Янв 2012 в 16:03

Это именно то, что он говорит. Он установит информацию «заголовка» для следующего .

Заголовок — это в значительной степени пара ключ / значение. Он используется для передачи метаинформации на целевой сервер для текущего запроса. В вашем конкретном случае он используется, чтобы сообщить серверу, какой тип контента используется для этого запроса.

3

jAndy
16 Янв 2012 в 16:04

HTTP-запросы — это сообщения, передаваемые из одной компьютерной системы в другую в соответствии с установленной процедурой («протокол» — здесь H yper T ext T перевод) P rotocol), чтобы делать такие вещи, как отправка данных, запрос данных для отправки обратно, обновление ранее отправленных данных и т. д.

Заголовок — это, по сути, фрагмент информации о данных в теле HTTP-запроса. Его цель — сообщить машине, получающей запрос, какой тип данных заключен в теле запроса, его форматировании, используемом языке, для установки файла cookie, дате, хост-машине и т. Д.

В HTTP-запрос может быть помещено более одного заголовка, и каждый заголовок имеет компонент «имя» и «значение». На веб-страницах они выглядят как

И вы найдете их чуть ниже верхней части веб-страницы внутри элемента.

Чтобы позволить людям отправлять HTTP-запросы из функции JavaScript, мы создаем новый объект XMLHttpRequest, так же как ваш код делает это с

К этому новому пустому объекту вы намереваетесь добавить данные. Несмотря на свое название, XMLHttpRequest также позволяет отправлять данные в нескольких форматах, отличных от XML, например HTML-код, текст, JSON и т. Д. В вашем примере каждое имя данных будет отделено от его значения символом «=», а каждая пара данных / значений будет отделена от следующей пары символом «&». Этот вид форматирования известен как кодирование URL.

Мы должны сообщить принимающему компьютеру, как кодируются данные в теле HTTP-запроса. Для этого существует , который добавляется в запрос с помощью метода. setRequestHeader (.. ) . Этот метод использует 2 параметра: имя заголовка и значение заголовка. Вся эта операция достигается в линии

Этот метод setRequestHeader (..) должен быть применен к запросу после того, как запрос характеризуется методом open (…) , но before : окончательный запрос отправляется методом send (.) .

Метод open (…) определяет: (1) тип HTTP-запроса, например, GET / POST / PUT и т.д .; (2) веб-страница, которая содержит сценарий обработки для этого запроса, например, некоторый .php файл или конечная точка запроса Node.js, которая делает соответствующий запрос к внутренней базе данных; и (3) характер динамики запроса, например, асинхронным запросам присваивается значение «истина», синхронным запросам присваивается «ложь».

Метод send (.) присоединяет данные для отправки в теле запроса, в вашем случае это переменная с именем ‘parameters’.

На ваш более широкий вопрос о том, в каких ситуациях используется setRequestHeader (..) , я бы сказал, что он используется в большинстве ситуаций HTTP-запросов. Но добавлены в тело HTTP-запрос вызывает настройку по умолчанию для заголовка «Content-Type».

3

Trunk
31 Янв 2020 в 15:54

Ограничения IE9-

В IE9- используется , который представляет собой урезанный .

На него действуют ограничения:

  • Протокол нужно сохранять: запросы допустимы с HTTP на HTTP, с HTTPS на HTTPS. Другие протоколы запрещены.
  • Метод имеет только два параметра. Он всегда асинхронный.
  • Ряд возможностей современного стандарта недоступны, в частности:
    • Недоступны методы, кроме GET или POST.
    • Нельзя добавлять свои заголовки, даже нельзя указать свой для запроса, он всегда .
    • Нельзя включить передачу кук и данных HTTP-авторизации.
  • В IE8 в режиме просмотра InPrivate кросс-доменные запросы не работают.

Современный стандарт XMLHttpRequest предусматривает средства для преодоления этих ограничений, но на момент выхода IE8 они ещё не были проработаны, поэтому их не реализовали. А IE9 исправил некоторые ошибки, но в общем не добавил ничего нового.

Поэтому на сайтах, которые хотят поддерживать IE9-, то на практике кросс-доменные запросы редко используют, предпочитая другие способы кросс-доменной коммуникации. Например, динамически создаваемый тег или вспомогательный с другого домена. Мы разберём эти подходы в последующих главах.

Как разрешить кросс-доменные запросы от доверенного сайта в IE9-?

Разрешить кросс-доменные запросы для «доверенных» сайтов можно в настройках IE, во вкладке «Безопасность», включив пункт «Доступ к источникам данных за пределами домена».

Обычно это делается для зоны «Надёжные узлы», после чего в неё вносится доверенный сайт. Теперь он может делать кросс-доменные запросы .

Этот способ можно применить для корпоративных сайтов, а также в тех случаях, когда посетитель заведомо вам доверяет, но почему-то (компьютер на работе, админ запрещает ставить другой браузер?) хочет использовать именно IE. Например, он может предлагаться в качестве дополнительной инструкции «как заставить этот сервис работать под IE».

В IE разрешён другой порт

В кросс-доменные ограничения IE не включён порт.

То есть, можно сделать запрос с на , и в IE он не будет считаться кросс-доменным.

Это позволяет решить некоторые задачи, связанные с взаимодействием различных сервисов в рамках одного сайта. Но только для IE.

Расширенные возможности, описанные далее, поддерживаются всеми современными браузерами, кроме IE9-.

GET и POST-запросы. Кодировка.

Во время обычного submit’а формы браузер сам кодирует значения полей и составляет тело GET/POST-запроса для посылки на сервер. При работе через XmlHttpRequest, это нужно делать самим, в javascript-коде. Большинство проблем и вопросов здесь связано с непониманием, где и какое кодирование нужно осуществлять.

Вначале рассмотрим общее кодирование запросов, ниже — правильную работу с русским языком для windows-1251.

Существуют два вида кодирования HTTP-запроса. Основной — urlencoded, он же — стандартное кодирование URL. Пробел представляется как %20, русские буквы и большинство спецсимволов кодируются, английские буквы и дефис оставляются как есть.

Способ, которым следует кодировать данные формы при submit’е, задается в ее HTML-таге:

<form method="get"> // метод GET с кодировкой по умолчанию
<form method="post" enctype="application/x-www-form-urlencoded"> // enctype явно задает кодировку
<form method="post"> // метод POST с кодировкой по умолчанию (urlencoded, как и предыдущая форма)

Если форма submit’ится обычным образом, то браузер сам кодирует (urlencode) название и значение каждого поля данных ( и т.п.) и отсылает форму на сервер в закодированном виде.

Формируя XmlHttpRequest, мы должны формировать запрос «руками», кодируя поля функцией .

Конечно, пропускать через encodeURIComponent стоит только те переменные, в которых могут быть спецсимволы или не английские буквы, т.е которые и будут как раз закодированы.

Например, для посылки GET-запроса с произвольными параметрами name и surname, их необходимо закодировать вот так:

// Пример с GET
...
var params = 'name=' + encodeURIComponent(name) + '&surname=' + encodeURIComponent(surname)
xmlhttp.open("GET", '/script.html?'+params, true)
...
xmlhttp.send(null)

В методе POST параметры передаются не в URL, а в теле, посылаемом через . Поэтому нужно указывать не в адресе, а при вызове

Кроме того, при POST обязателен заголовок Content-Type, содержащий кодировку. Это указание для сервера — как обрабатывать (раскодировать) пришедший запрос.

// Пример с POST
...
var params = 'name=' + encodeURIComponent(name) + '&surname=' + encodeURIComponent(surname)
xmlhttp.open("POST", '/script.html', true)
xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
...
xmlhttp.send(params)

Заголовки Content-Length, Connection в POST-запросах, хотя их и содержат некоторые «руководства», обычно не нужны. Используйте их, только если Вы действительно знаете, что делаете.

Запросы multipart/form-data

Второй способ кодирования — это отсутствие кодирования. Например, кодировать не нужно для пересылки файлов. Он указывается в форме (только для POST) так:

<form method="post" enctype="multipart/form-data">

В этом случае при отправке данных на сервер ничего не кодируется. А сервер, со своей стороны, посмотрев на Content-Type(=multipart/form-data), поймет, что пришло.

Возможности XmlHttpRequest позволяют создать запрос с любым телом. Например, можно вручную сделать POST-запрос, загружающий на сервер файл. Функционал создания
таких запросов есть, в частности, во фреймворке . Но можно реализовать его и самому, прочитав о нужном формате тела POST и заголовках.

Кодировка (языковая)

Если Вы используете только UTF-8 — пропустите эту секцию.

Все идущие на сервер параметры GET/POST, кроме случая multipart/form-data, кодируются в UTF-8. Не в кодировке страницы, а именно в UTF-8. Поэтому, например, в PHP их нужно при необходимости перекодировать функцией iconv.

<?php
// ajax.php
$name = iconv('UTF8','CP1251',$_GET);
?>

С другой стороны, ответ с сервера браузер воспринимает именно в той кодировке, которая указана в заголовке ответа Content-Type. Т.е, опять же, в PHP, чтобы браузер воспринял ответ в windows-1251 и нормально отобразил данные на странице в windows-1251,
нужно послать заголовок с кодировкой в php-коде, например так:

<?php
// ajax.php
header('Content-Type: text/plain; charset=utf-8');
?>

Или же, такой заголовок должен добавить сервер. Например, в apache автоматически добавляется кодировка опцией:

# в конфиге апача
AddDefaultCharset windows-1251

Изменения состояния XHR

Если метод был вызван успешно, свойству объекта XMLHttpRequest будет присвоено значение 1 (Open). После того как заголовки HTTP-ответа были получены, для свойства readyState объекта XHR назначается значение 2 (HEADERS_RECEIVED). После загрузки содержимого ответа HTTP свойству readyState объекта XHR должно быть присвоено значение 3 (Loading).

После завершения загрузки HTTP-ответа для свойства readyState объекта XHR должно быть назначено значение 4 (Done). Слушатель будет реагировать только на изменения состояния, которые возникают после его определения. Чтобы обнаружить состояния 1 и 2, слушатель должен быть определен до вызова open. Открытый метод должен быть применен до вызова send.

Этот метод прерывает запрос, если объект readyState объекта XHR еще не стал 4 (Done). Метод abort гарантирует, что обработчик обратного вызова не будет вызван во время асинхронного запроса. Некоторые библиотеки AJAX используют прерывание, чтобы отменить потенциальный дубликат или испорченные запросы.

§Downloading Data with XHR

XHR can transfer both text-based and binary data. In fact, the browser
offers automatic encoding and decoding for a variety of native data
types, which allows the application to pass these types directly to XHR
to be properly encoded, and vice versa, for the types to be automatically
decoded by the browser:

Fixed-length binary data buffer

Binary large object of immutable data

Parsed HTML or XML document

JavaScript object representing a simple data structure

A simple text string

Either the browser can rely on the HTTP content-type negotiation to
infer the appropriate data type (e.g., decode an
application/json response into a JSON object), or the
application can explicitly override the data type when initiating the XHR
request:

var xhr = new XMLHttpRequest();
xhr.open('GET', '/images/photo.webp');
xhr.responseType = 'blob'; 

xhr.onload = function() {
  if (this.status == 200) {
    var img = document.createElement('img');
    img.src = window.URL.createObjectURL(this.response); 
    img.onload = function() {
        window.URL.revokeObjectURL(this.src); 
    }
    document.body.appendChild(img);
  }
};

xhr.send();
  1. Set return data type to blob

  2. Create unique object URI from blob and set as image source

  3. Release the object URI once image is loaded

Note that we are transferring an image asset in its native format,
without relying on base64 encoding, and adding an image element to the
page without relying on data URIs. There is no network transmission
overhead or encoding overhead when handling the received binary data in
JavaScript! XHR API allows us to script efficient, dynamic applications,
regardless of the data type, right from JavaScript.

Synchronous request

Note: Starting with Gecko 30.0 (Firefox 30.0 / Thunderbird 30.0 / SeaMonkey 2.27), Blink 39.0, and Edge 13, synchronous requests on the main thread have been deprecated due to the negative effects to the user experience.

Synchronous XHR often causes hangs on the web. But developers typically don’t notice the problem because the hang only manifests during poor network conditions or slow server response. Synchronous XHR is now in deprecation state. Developers are recommended to move away from the API.

All new XHR features such as or aren’t allowed for synchronous XHR. Doing so would invoke .

This example demonstrates how to make a simple synchronous request.

Line 3 sends the request. The parameter indicates that no body content is needed for the request.

Line 5 checks the status code after the transaction is completed. If the result is 200 — HTTP’s «OK» result — the document’s text content is output to the console.

One of the few cases in which a synchronous request does not usually block execution is the use of within a .

(the main page):

(the target of the synchronous invocation):

Hello World!!

(the ):

Note: The effect, because of the use of the , is however asynchronous.

It could be useful in order to interact in the background with the server or to preload some content. See Using web workers for examples and details.

There are some cases in which the synchronous usage of XMLHttpRequest was not replaceable, like during the and events. You should consider using the API with flag. When with isn’t available, you can consider using the navigator.sendBeacon API can support these use cases typically while delivering a good UX.

The following example (from the sendBeacon docs) shows a theoretical analytics code that attempts to submit data to a server by using a synchronous XMLHttpRequest in an unload handler. This results in the unloading of the page to be delayed.

Using the method, the data will be transmitted asynchronously to the web server when the User Agent has had an opportunity to do so, without delaying the unload or affecting the performance of the next navigation.

The following example shows a theoretical analytics code pattern that submits data to a server by using the method.

JS Tutorial

JS HOMEJS IntroductionJS Where ToJS OutputJS StatementsJS SyntaxJS CommentsJS VariablesJS LetJS ConstJS OperatorsJS ArithmeticJS AssignmentJS Data TypesJS FunctionsJS ObjectsJS EventsJS StringsJS String MethodsJS String SearchJS String TemplatesJS NumbersJS Number MethodsJS ArraysJS Array MethodsJS Array SortJS Array IterationJS Array ConstJS DatesJS Date FormatsJS Date Get MethodsJS Date Set MethodsJS MathJS RandomJS BooleansJS ComparisonsJS ConditionsJS SwitchJS Loop ForJS Loop For InJS Loop For OfJS Loop WhileJS BreakJS IterablesJS SetsJS MapsJS TypeofJS Type ConversionJS BitwiseJS RegExpJS ErrorsJS ScopeJS HoistingJS Strict ModeJS this KeywordJS Arrow FunctionJS ClassesJS JSONJS DebuggingJS Style GuideJS Best PracticesJS MistakesJS PerformanceJS Reserved Words

Ограничения безопасности. Кросс-доменный XMLHttpRequest

Для ограничения XmlHttpRequest используется философия «Same Origin Policy». Она очень проста — каждый сайт в своей песочнице. Запрос можно делать только на адреса
с тем же протоколом, доменом, портом, что и текущая страница.

Т.е, со страницы на адресе http://site.com нельзя сделать XmlHttpRequest на адрес https://site.com, http://site.com:81 или http://othersite.com

Это создает проблему, если хочется взять контент с другого сайта. Как правило, в этом случае вместо XmlHttpRequest используются другие средства, например, загрузка через
динамически создаваемый тег

Проксирование

Самый простой способ обойти это ограничение — проксирование. Допустим, мы хотим сделать запрос с http://site.com на http://remote.com/get.html.

Чтобы обойти ограничение, вместо указания remote.com в методе open(), там ставится специальный URL вида http://site.com/proxy/remote.com/get.html. Так что запрос приходит на наш веб-сервер, который проксирует его на сервер site.com, который в свою очередь обрабатывает этот запрос, как нужно.

Если remote.com находится на другом сервере, то серверу site.com придется проксировать посетителю как запрос, так и ответ. При этом, разумеется, никак не будут задействованы куки remote.com, так что не получится отдельной авторизации, учета пользователей или чтото в этом роде с отдельными куками.

Проксирование настраивается соответствующим модулем (mod_proxy, proxy module и т.п.) веб-сервера для всех адресов, начинающихся на /proxy.

Например, при использовании web-сервера Apache, для проксирования нужны директивы ProxyPass, ProxyPassReverse. Кроме того, доступны еще модули, которые по необходимости правят урлы, разархивируют контент

Использование наддомена

Часто кроссбраузерные запросы — это

  1. Способ обойти ограничения в 2 одновременных соединения к одному домену-порту.
  2. Способ использовать два разных сервера в общении с посетителем. Например, на chat.site.ru — чат-демон, на www.site.ru — веб-сервер.

Кросс-доменные запросы с поддомена типа http://a.site.com, http://b.site.com на базовый домен site.com допустимы при использовании свойства document.domain, которое надо установить в site.com

// на странице a.site.com
...
document.domain='site.com'
...
// все, теперь могу делать XmlHttpRequest на site.com
xmlhttp.open(..'http://site.com/feedme.php'..)

Запрос на старый домен

В браузере Internet Explorer, чтобы сделать запрос на старый домен a.site.com, нужно вернуть свойство document.domain обратно. В остальных браузерах это приводит к ошибке, поэтому можно оформить код типа такого:

var oldDomain = document.domain
document.domain = "site.com"
try {
    // для IE, в остальных браузерах ошибка...
    document.domain = oldDomain;
} catch(e) {  /* ... но в них все и так работает */ }
//... работаем с a.site.com ...

Same origin и фреймы

Приятным бонусом свойства document.domain является возможность коммуникации между фреймами/ифреймами на одном домене.

То есть, например, если

  • во фрейме с адреса http://a.site.com установлен document.domain=’site.com’,
  • на фрейме с адреса http://b.site.com установлен домен document.domain=’site.com’
  • на фрейме с адреса http://site.com установлен (обязательно!) домен document.domain=’site.com’

То эти три фрейма могут свободно общаться посредством javascript и XmlHttpRequest.

Обычно такая коммуникация используется при создании чатов/событий с сервера, когда на site.com находится основной веб-сервер, а на chat.site.com висит чат-демон.

Internet Explorer trusted zone

Любые запросы допустимы между сайтами, находящимися в доверенной (trusted) зоне Internet Explorer. Так что, внутренний корпоративный портал может быть у всех пользователей в этой зоне, и он сможет делать запросы к любым сайтам.

XhrIframeProxy

Еще один хитрый подход называется , и позволяет делать XmlHttpRequest к любым доменам при помощи хитрого iframe-хака. Он основан на том, что фреймы с разных доменов могут читать и менять друг у друга anchor, т.е часть адреса после решетки ‘#’. За счет этого организуется специальный протокол, по которому «проксируется» XmlHttpRequest.

Этот метод, в принципе, вполне жизнеспособен, особенно для небольшого объема данных.

Кросс-доменные запросы в FF3/IE8/Opera9..

В спецификации HTML 5 предусмотрены кросс-доменные запросы .

Создатели Firefox и Opera реализовали этот вариант, см. например MDC: .

Разработчики IE8 пошли другим путем и предлагают .

Оба способа вполне жизнеспособны и уже пригодны для использования в интранет-приложениях, когда на всех машинах администратор ставит одинаковый браузер, например, Firefox 3 ?

Instance Properties

readyState : Number  readonly

The current state of . Will be one of , , , , or .

Example:

var request = new XMLHttpRequest();
request.onreadystatechange = function() {
console.log(‘readyStatechange: ‘ + request.readyState);
};
console.log(‘Before open: ‘ + request.readyState);
request.open(‘GET’, ‘/’);
request.send();
console.log(‘After send: ‘ + request.readyState);

Results:

response : Object  readonly

Returns the response from the server in the type specified by . Only valid after the event fires.

Example:

var request = new XMLHttpRequest();
request.responseType = ‘arraybuffer’;
request.open(‘GET’, ‘/’);
request.onload = function() {
console.log(request.response);
console.log(request.response.byteLength);
};
request.send();

Results:

responseText : String  readonly

Returns the response from the server as a string. Only valid after the event fires and if is set to (the default) or .

Example:

var request = new XMLHttpRequest();
request.open(‘GET’, ‘/’, /* async = */ false);
request.send();
console.log(request.responseText.substring(0, 150));
console.log(‘…’);

Results:

responseType : String

Determines the type returned by . Must be set to one of the following:

returns
(default) Same as

Must be set before reaches .

Example:

var request = new XMLHttpRequest();
request.responseType = ‘arraybuffer’;
request.open(‘GET’, ‘/’);
request.onload = function() {
console.log(request.response);
console.log(request.response.byteLength);
};
request.send();

Results:

responseXML : Document  readonly

status : Number  readonly

The http status code for the request. See for a description of the code.

Example:

var request = new XMLHttpRequest();
request.open(‘GET’, ‘/’, /* async = */ false);
request.send();
console.log(‘status code: ‘ + request.status);

request = new XMLHttpRequest();
request.open(‘GET’, ‘NonExistentPage/’, /* async = */ false);
request.send();
console.log(‘status code: ‘ + request.status);

Results:

statusText : String  readonly

A description of the .

Example:

var request = new XMLHttpRequest();
request.open(‘GET’, ‘/’, /* async = */ false);
request.send();
console.log(‘status: ‘ + request.statusText);

request = new XMLHttpRequest();
request.open(‘GET’, ‘NonExistentPage/’, /* async = */ false);
request.send();
console.log(‘status: ‘ + request.statusText);

Results:

timeout : Number

upload : XMLHttpRequestUpload  readonly

Returns an object associated with this XMLHttpRequest that can be used to track the upload status of the call.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Adblock
detector