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>

Как заставить метод send объекта XMLHttpRequest дублировать указанный выше HTTP-поток?

Вы приняли ответ через 9 лет! Вы второй в стеке обмена.

peterh - Reinstate Monica 24.03.2017 19:15
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
20
1
57 826
7
Перейти к ответу Данный вопрос помечен как решенный

Ответы 7

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

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

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

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

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

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


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

Я не понимаю, что вы указали событие 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);
} 
Ответ принят как подходящий

Вы можете создать запрос multipart / form-data самостоятельно (подробнее об этом читайте в http://www.faqs.org/rfcs/rfc2388.html), а затем использовать метод send (например, xhr.send (your-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.

Святой ***. Спасибо! Пытался выяснить, как это сделать вручную в течение часа, когда мой сервер не мог проанализировать то, что я отправил

Romuald Brunet 31.12.2017 16:41

Было бы здорово иметь небольшое резюме того, что вы считаете важным в этих ссылках, на случай, если серверы будут отключены.

everyone 14.08.2018 11:59

Content-Disposition: form-data, name

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

Вот современный способ использования FormData (полный документ @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>

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

Другие вопросы по теме