Можно ли выполнить асинхронную междоменную загрузку файла?

Возможно! Читайте ниже.

Прежде всего, позвольте мне использовать эту диаграмму, чтобы объяснить, как можно добиться асинхронной загрузки файлов :


Извините. Я отключил один из своих доменов, и изображение исчезло. Хотя это был действительно красивый образ. Это было до того, как я узнал, что Stack Overflow позволяет загружать изображения через Imgur.


Как видите, фокус состоит в том, чтобы позволить HTTP-ответу загружаться в скрытый элемент IFRAME вместо самой страницы. (Это делается путем установки свойства target элемента FORM при отправке FORM с помощью JavaScript.)

Это работает. Однако проблема, с которой я столкнулся, заключается в том, что серверный сценарий находится в другом домене . FORM-submit - это междоменный HTTP-запрос. Теперь в серверном скрипте включен CORS, который дает моей веб-странице права на чтение данных ответа HTTP-запросов, сделанных с моей страницы, в этот скрипт, но это работает, только если я получаю HTTP-ответ через Ajax, эрго, JavaScript.

Однако в этом случае ответ направлен на элемент IFRAME. И как только ответ XML попадает в IFRAME, его URL-адрес будет сценарием удаления, например 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.

И, как если бы этот вопрос недостаточно неразрешим, позвольте мне исключить эти решения :

  1. easyXDM и аналогичные методы, которые требуют конечной точки на удаленный домен,

  2. изменение ответа XML (для включения элемента SCRIPT),

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

Итак, помимо этих двух решений, можно ли это сделать?


Это можно сделать !!

Оказывается, можно подделать XHR-запрос (Ajax-запрос), который имитирует использует multipart / form-data FORM submit (который используется на изображении выше для загрузки файла на сервер).

Хитрость заключается в использовании конструктора FormData - чтение эта статья Mozilla Hacks для получения дополнительной информации.

Вот как вы это делаете:

// STEP 1
// retrieve a reference to the 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);

Вышеупомянутый метод выполняет асинхронную загрузку файлов, которая эквивалентна обычной загрузке файлов, описанной на изображении выше и достигается путем отправки этой формы:

Like a Boss :)

47
задан 16 revs, 2 users 100% 30 March 2014 в 01:58
поделиться