Это возможно! Читайте ниже.
Прежде всего, позвольте мне использовать эту диаграмму, чтобы объяснить, как можно добиться асинхронной загрузки файлов:
К сожалению. Я закрыл один из моих доменов, и изображение исчезло. Это был действительно хороший образ. Это было до того, как я узнал, что Qaru позволяет загружать изображения через Imgur.
Как вы можете видеть, трюк заключается в том, чтобы загрузить HTTP-ответ в скрытый элемент IFRAME вместо самой страницы. (Это делается установкой свойства target
элемента FORM при отправке FORM с помощью JavaScript.)
Это работает. Однако проблема, с которой я сталкиваюсь, заключается в том, что серверная сторона script находится в другом домене. FORM-submit - это междоменный HTTP-запрос. Теперь серверная сторона script имеет включенную CORS, которая дает моей веб-странице права на чтение данных ответа HTTP-запросов, сделанных с моей страницы, на этот script - но это работает только в том случае, если я получаю HTTP- ответ через Ajax, ergo, JavaScript.
Однако, в этом случае ответ направлен на элемент IFRAME. И как только XML-ответ попадет в IFRAME, его URL-адрес будет удаляться script - например. http://remote-domain.com/script.pl
.
К сожалению, CORS не охватывает этот случай (по крайней мере, я думаю). Я не могу прочитать содержимое IFRAME, так как его URL-адрес не соответствует URL-адресу страницы (другой домен). Я получаю эту ошибку:
Небезопасная попытка JavaScript для доступа к фрейму с URL-адресом hxxp://remote-domain.com/ script.pl из фрейма с URL-адресом hxxp://my-domain.com/outer.html. Домены, протоколы и порты должны матч.
И поскольку содержимое IFRAME является XML-документом, внутри IFRAME нет кода JavaScript, который мог бы использовать postMessage
или что-то в этом роде.
Итак, мой вопрос: Как я могу получить содержимое XML из IFRAME?
Как я уже говорил выше, я могу напрямую получить междоменные HTTP-ответы (CORS включен), но кажется, что я не могу читать междоменные HTTP-ответы после их загрузки в IFRAME.
И как если бы этот вопрос не был достаточно неразрешим, позвольте мне исключить эти решения:
-
easyXDM и аналогичные методы, которые требуют конечной точки в удаленном домене,
-
изменение ответа XML (включение элемента script),
-
серверный прокси - я понимаю, что у меня может быть серверный script в моем домене, который может служить прокси.
Итак, не считая этих двух решений, можно ли это сделать?
Это можно сделать!!
Оказывается, можно подделать XHR-запрос (Ajax-запрос), который имитирует submit multipart/form-data
FORM submit (который используется на изображении выше для загрузки файла на сервер).
Хитрость заключается в использовании конструктора FormData
- прочитайте эту статью Mozilla Hacks для получения дополнительной информации.
Вот как вы это делаете:
// STEP 1
// retrieve a reference to the file
// <input type="file"> elements have a "files" property
var file = input.files[0];
// STEP 2
// create a FormData instance, and append the file to it
var fd = new FormData();
fd.append('file', file);
// STEP 3
// send the FormData instance with the XHR object
var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://remote-domain.com/script.pl', true);
xhr.onreadystatechange = responseHandler;
xhr.send(fd);
Вышеупомянутый метод выполняет асинхронный файл-uplaod, который эквивалентен обычной загрузке файла, описанной на изображении выше, и достигается путем отправки этой формы:
<form action="http://remote-domain.com/script.pl"
enctype="multipart/form-data" method="post">
<input type="file" name="file">
</form>