XMLHttpRequest2, или, точнее, XMLHttpRequest Level 2, — это тот самый, ответственный за AJAX-функционал объект XMLHttp-Request, оснащенный новыми возможностями.
Все они — по сути, исправления недостатков предыдущей реализации компонента, имеющей уже огромные заслуги перед вебом, но, увы, неидеальной.
Прежде всего нормальная работа с XMLHttpRequest заканчивалась там, где надо было выполнить кроссдоменный запрос. Работа XMLHttpRequest подчинялась политике ограничения домена (same-origin policy), позволяющей отправлять запросы только в пределах этого самого домена. Ограничения, накладываемые производителями браузеров на подобного рода взаимодействия, конечно, разумны, иначе Всемирная паутина просто захлебнулась бы в XSS-атаках, но все-таки иногда кроссдоменное взаимодействие просто необходимо. На тему того, как заставить XMLHttpRequest работать с разными доменами, написана не одна статья, обычно для этого требовались трюки разной степени корявости.
Вторая проблема — асинхронная передача двоичных данных (например, картинок). Тут все проще — такие вещи вообще не были предусмотрены. Из положения выходили еще более некрасивыми методами, стыдливо пряча на странице фрейм с формой загрузки или организуя получение файла в виде бинарной строки.
Еще одна проблема, быть может, менее очевидная, заключалась в отсутствии механизмов проверки состояния загрузки контента, механизма индикации.
И вот теперь не нужно никаких хаков, чтобы выполнять такие операции, как кроссдоменные запросы, процесс загрузки файлов, загрузка и отправка двоичных данных.
Прежде всего XMLHttpRequest Level 2 действует в рамках новой модели взаимодействия — протокола Cross Origin Resource Sharing (CORS), позволяющего проводить запросы с одного домена на другой. На практике при этом в схеме взаимодействия ничего не меняется, просто браузер, в случае обращения к другому, вместо выбрасывания исключения («origin mismath») добавляет к запросам один заголовок:
Access-Control-Allow-Origin: Http://othersite. com
Который может быть выдан как одному сайту, так и целому домену. Этот параметр эквивалентен объекту event. origin в Web Messages.
Вот как прозрачно происходит xmlhttp-запрос с одного домена на другой:
Var xhr = new XMLHttpRequest();
Xhr. open(‘GET’, ‘Http://www. otherdomian. com/hello. php’);
Xhr. onload = function(e) {
Var data = JSON. parse(this. response);
}
Xhr. send():
Даже неинтересно — на пользовательской стороне ровным счетом ничего не изменялось!
Для работы с данными вида, отличного от строк, появились свойства responseType и response, позволяющие явно указать браузеру формат ожидаемых в результате ответа данных. После установки соответствующего значения responseType свойство XMLHttpRequest. response будет содержать значения в одном из следующих форматов: DOMString, ArrayBuffer, Blob, Document.
Вот как выглядит асинхронная отправка картинки с новым XMLHttpRequest:
Var xhr = new XMLHttpRequest(); xhr. open(‘GET’, ‘image. jpeg’, true); xhr. responseType = ‘frraybuffer’; xhr. onload = function(e){ if (this. status == 200) {
Var bilder = new BlobBuilder();
Bilder. append(this. response):
Var blob = bilder. getBlob(‘image. jpg’);
}
};
Xhr. send():
Вообще, про тип ArrayBuffer следует рассказать отдельно.
ArrayBuffer — это общий контейнер для бинарных данных с фиксированным объемом. Этот тип данных может применяться и применяется тогда, когда нужен буфер общего назначения для бинарных данных неопределенной структуры. Эти данные легко могут быть представлены в виде типизированного JavaScript-массива или просто ассоциативного массива (если вы не хотите пользоваться этим замечательным новшеством языка).
А вот так можно сделать то же самое, используя тип Blob (если у нас нет необходимости работать с отдельными байтами):
Var xhr = new XMLHttpRequest(); xhr. open(‘GET’, ‘/path/to/image. png’, true); xhr. responseType = ‘blob’; xhr. onload = function(e) { if (this. status == 200) { var blob = this. response;
Var img = document. createElement(‘img’); img. src = window. URL. createObjectURL(blob);
}
};
Xhr. send():
Данные в различных форматах теперь можно и отправлять на сервер. Вот примеры для тех же arrayBuffer и Blob:
Var uInt8Array = new Uint8Array([1, 2, 3]);
Xhr. send(uInt8Array. buffer);
Var blob = new BlobBuilder();
Blob. append(‘I am just blob fule…’); blob. getBlob(‘text/plain’);
Xhr. send(blobOrFile);
На практике такие возможности означают, что теперь для нас доступна, например, отправка файла по частям, а также загрузка и сохранение файла в HTML5 File System.
Еще одно полезное свойство обновленного элемента — возможность работы с данными, поступающими из формы в виде единого объекта — FormData(), инкрустирующего все элементы формы (да-да, и <input type="file">). Отправка данных при этом выглядит совершенно стандартно:
FormData = new FormData(form);
XMLHttpRequest. send(formData);
Тут form — объект HTML Form. А можно делать и так:
Var formData = new FormData(); formData. append(‘user’, ‘vanya’); formData. append(‘role’, ‘admin’); formData. append(‘id’, 17);
Xhr. send(formData);
Надо заметить, что разработчики, по-видимому, находились под сильным впечатлением возможностей и подходов библиотеки jquery, но разве это плохо?
Добавить комментарий