Иногда для представления передаваемых данных также используется формат XML. Данные в запросе информации о пиццерии можно было бы передавать не в формате представления данных форм и не в формате JSON представления JavaScript-объектов, а в формате XML-документа. Тело такого запроса могло бы иметь следующий вид:
<query>
<find zipcode="02134" radius="1km"> pizza </find>
</query>
Во всех примерах, встречавшихся до сих пор, аргументом метода
send
объекта
XMLHttpRequest
была строка или значение null. В действительности же этому методу можно также передать объект Document XML-документа. Пример 18.8 демонстрирует, как создать объект
Document
простого XML-документа и использовать его в качестве тела НТТР-запроса.
Пример 18.8. Выполнение запроса HTTP POST с XML-документом в качестве тела
// Параметры поиска "что", "где" и "радиус" оформляются в виде XML-документа // и отправляются по указанному URL-адресу. При получении ответа вызывает // указанную функцию
function postuery(url, what, where, radius, callback) {
var request = new XMLHttpRequest;
request.open("POST", url); // Методом POST на указанный url
request.onreadystatechange = function { // Простой обработчик
if (request.readyState === 4 && callback) callback(request);
};
// Создать XML-документ с корневым элементом <query>
var doc = document.implementation.createDocument("", "query", null);
var query = doc.documentElement; // Элемент <query>
var find = doc.createElement("find"); // Создать элемент <find>
find.appendChild(doc.createTextNode(what)); // И содержимое <find>
// Отправить данные в формате XML серверу.
// Обратите внимание, что заголовок Content-Type будет установлен автоматически,
request.send(doc);
}
Обратите
внимание, что пример 18.8 не устанавливает заголовок «Content-Type» запроса. Когда методу
send
передается XML-документ, то объект
XMLHttpRequest
автоматически установит соответствующий заголовок «Content-Type», если он не был установлен предварительно. Аналогично, если передать методу
send
простую строку и не установить заголовок «Content-Type», объект
XMLHttpRequest
автоматически добавит этот заголовок со значением «text/plain; charset=UTF-8». Программный код в примере 18.1 явно устанавливает этот заголовок, но в действительности для данных в простом текстовом виде этого не требуется.
18.1.3.4. Выгрузка файлов
Одна из особенностей HTML-форм заключается в том, что, если пользователь выберет файл с помощью элемента
<input type="file">
, форма отправит содержимое этого файла в теле POST-запроса. HTML-формы всегда позволяли выгружать файлы, но до недавнего времени эта операция была недоступна в прикладном интерфейсе
XMLHttpRequest
. Прикладной интерфейс, определяемый спецификацией «ХНН2», позволяет выгружать файлы за счет передачи объекта
File
методу
send.
В данном случае нельзя создать объект с помощью конструктора
File:
сценарий может лишь получить объект
File
, представляющий файл, выбранный пользователем. В броузерах, поддерживающих объекты
File
, каждый элемент
<input type="file">
имеет свойство
files
, которое ссылается на объект, подобный массиву, хранящий объекты
File
. Прикладной интерфейс буксировки (drag-and-drop) (раздел 17.7) также позволяет получить доступ к файлам, «сбрасываемым» пользователем на элемент, через свойство
dataTransfer.files
события «drop». Поближе с объектом
File
мы познакомимся в разделах 22.6 и 22.7. А пока будем рассматривать объект
File
как полностью непрозрачное представление выбранного пользователем файла, пригодное для выгрузки методом
send.
В примере 18.9 представлена ненавязчивая JavaScript-функция, добавляющая обработчик события «change» к указанным элементам выгрузки файлов, чтобы они автоматически отправляли содержимое любого выбранного файла методом POST на указанный адрес URL.
Пример 18.9. Выгрузка файла посредством запроса HTTP POST
// Отыскивает все элементы <input type=”file"> с атрибутом data-uploadto
// и регистрирует обработчик onchange, который автоматически отправляет
// выбранный файл по указанному URL-адресу "uploadto". Ответ сервера игнорируется.
whenReady(function { // Вызвать эту функцию после загрузки документа
var elts = document.getElementsByTagName("input”); // Все элементы input
for(var і = 0; і < elts.length; i++) { // Обойти в цикле
var input = elts[i];
if (input.type !== ’'file") continue; // Пропустить все, кроме
// элементов выгрузки файлов
var url = input.getAttribute("data-uploadto"); // Адрес выгрузки