Подтвердить что ты не робот

XMLHttpRequest POST multipart/form-data

Я хочу использовать XMLHttpRequest в JavaScript для POST формы, которая включает элемент ввода типа файла, чтобы я мог избежать обновления страницы и получить полезный XML обратно.

Я могу отправить форму без обновления страницы, используя JavaScript, чтобы установить целевой атрибут формы в iframe для MSIE или объект для Mozilla, но это имеет две проблемы. Незначительная проблема заключается в том, что цель не совместима с W3C (поэтому я установил ее в JavaScript, а не в XHTML). Основная проблема заключается в том, что событие onload не срабатывает, по крайней мере, не в Mozilla на OS X Leopard. Кроме того, XMLHttpRequest сделал бы более красивый код ответа, потому что возвращаемые данные могли быть XML, а не ограничены XHTML, как в случае с iframe.

Отправка формы приводит к HTTP, который выглядит следующим образом:

Content-Type: multipart/form-data;boundary=<boundary string>
Content-Length: <length>
--<boundary string>
Content-Disposition: form-data, name="<input element name>"

<input element value>
--<boundary string>
Content-Disposition: form-data, name=<input element name>"; filename="<input element value>"
Content-Type: application/octet-stream

<element body>

Как мне получить метод отправки объекта XMLHttpRequest для дублирования вышеуказанного потока HTTP?

4b9b3361

Ответ 1

Вы можете сами создать запрос "multipart/form-data" (подробнее об этом читайте http://www.faqs.org/rfcs/rfc2388.html), а затем используйте send (т.е. xhr.send(ваши-multipart-form-data)). Аналогично, но проще, в Firefox 4+ (также в Chrome 5+ и Safari 5+) вы можете использовать интерфейс FormData, который помогает создавать такие запросы. Метод send хорош для текстового содержимого, но если вы хотите отправить двоичные данные, такие как изображения, вы можете сделать это с помощью метода sendAsBinary, который был запущен с Firefox 3.0. Подробнее о том, как отправлять файлы через XMLHttpRequest, см. http://blog.igstan.ro/2009/01/pure-javascript-file-upload.html.

Ответ 2

Нет никакого способа получить доступ к полю ввода файла внутри javascript, так что для загрузки файлов ajax не существует только javascript.

Есть обходной путь, например с использованием iframe.

Другой вариант - использовать что-то вроде SWFUpload или Google Gears

Ответ 3

Я не понимаю, почему iframe (невидимый) подразумевает XHTML, а не ЛЮБОЙ контент. Если вы используете iframe, вы можете установить событие onreadystatechange и дождаться "complete". Затем вы можете использовать frame.window.document.innerHTML(пожалуйста, кто-то меня исправит), чтобы получить результат строки.

var lFrame = document.getElementById('myframe');
lFrame.onreadystatechange = function()
{
   if (lFrame.readyState == 'complete')
   {
      // your frame is done, get the content...
   }
};

Ответ 4

Вам понадобится POST для IFrame, чтобы заставить это работать, просто добавьте целевой атрибут в свою форму, где вы укажете ID IFrame. Что-то вроде этого:


<form method="post" target="myiframe" action="handler.php">
...
</form>
<iframe id="myiframe" style="display:none" />

Ответ 5

Я запутался в событии onload, которое вы указали, оно находится на странице или в iframe?, первый ответ правильный. Невозможно сделать это, используя чисто xmlhttprequest, если то, что вы хотите добиться, вызывает какой-либо метод после того, как ответ существует на iframe, просто проверьте, есть ли у него контент уже или нет, с помощью сценариев DOM, затем запускайте метод.

чтобы прикрепить событие onload к iframe

if(window.attachEvent){
 document.getElementById(iframe).attachEvent('onload', some_method);
}else{
 document.getElementById(iframe).addEventListener('load', some_method, false);
} 

Ответ 6

Content-Disposition: form-data, name

Вы должны использовать точку с запятой, например: Content-Disposition: form-data; имя

Ответ 7

Вот обновленный способ использования FormData (full doc @MDN)

Script:

var form = document.querySelector('#myForm');
form.addEventListener("submit", function(e) {
    var xhr = new XMLHttpRequest();
    xhr.open("POST", this.action);
    xhr.addEventListener("load", function(e) {
        // Your callback
    });

    xhr.send(new FormData(this));

    e.preventDefault();
});

(из этой основной формы)

<form id="myForm" action="..." method="POST" enctype="multipart/form-data">
    <input type="file" name="file0">
    <input type="text" name="some-text">
    ...
</form>

Еще раз спасибо Алексу Поло за его ответ