XMLHttpRequest POST multipart / form-data

17

Я хочу использовать 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?

    
задан Robin like the bird 01.10.2008 в 00:27
источник
  • Вы приняли ответ через 9 лет! Вы занимаете второе место в stackexchange. –  peterh 24.03.2017 в 17:15

7 ответов

23

Вы можете самостоятельно создать запрос «multipart / form-data» (подробнее об этом читайте Ссылка ) а затем используйте метод send (т. е. xhr.send (ваши-multipart-form-data)). Аналогично, но проще, в Firefox 4+ (также в Chrome 5+ и Safari 5+) вы можете использовать FormData , который помогает создавать такие запросы. Метод send хорош для текстового содержимого, но если вы хотите отправить двоичные данные, такие как изображения, вы можете сделать это с помощью метода sendAsBinary , который был вокруг, начиная с Firefox 3.0. Подробнее о том, как отправлять файлы через XMLHttpRequest , см. Ссылка .     

ответ дан Alex Polo 22.11.2010 в 00:02
источник
  • Святой ***. Спасибо! Попытался выяснить, как это сделать вручную в течение часа, когда мой сервер не может разобрать то, что я отправил –  Romuald Brunet 31.12.2017 в 14:41
5

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

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

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

    
ответ дан TonyB 01.10.2008 в 00:42
источник
0

Я не понимаю, почему 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...
   }
};
    
ответ дан helios 01.10.2008 в 00:42
источник
0

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


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

    
ответ дан mmattax 01.10.2008 в 00:45
источник
0

Я запутался в событии 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);
} 
    
ответ дан Komang 04.10.2008 в 20:15
источник
0
  

Content-Disposition: form-data, name

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

    
ответ дан Aldekein 29.06.2011 в 17:27
источник
0

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

Сценарий:

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>

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

    
ответ дан Romuald Brunet 31.12.2017 в 14:58
источник