Стандарт XMLHttpRequest Level 2 (все еще рабочий проект) определяет интерфейс FormData
. Этот интерфейс позволяет добавлять объекты File
к XHR-запросам (Ajax-запросы).
Btw, это новая функция - в прошлом использовался "скрытый-iframe-трюк" (читал об этом в мой другой вопрос).
Вот как это работает (пример):
var xhr = new XMLHttpRequest(),
fd = new FormData();
fd.append( 'file', input.files[0] );
xhr.open( 'POST', 'http://example.com/script.php', true );
xhr.onreadystatechange = handler;
xhr.send( fd );
где input
- это поле <input type="file">
, а handler
- обработчик успеха для запроса Ajax.
Это прекрасно работает во всех браузерах (опять же, кроме IE).
Теперь я хотел бы, чтобы эта функциональность работала с jQuery. Я пробовал это:
var fd = new FormData();
fd.append( 'file', input.files[0] );
$.post( 'http://example.com/script.php', fd, handler );
К сожалению, это не сработает (вызывается ошибка "Незаконный вызов" - снимок экрана здесь). Я предполагаю, что jQuery ожидает простой объект "ключ-значение", представляющий имена полей/значений формы, и экземпляр FormData
, который я передаю, по-видимому, несовместим.
Теперь, поскольку можно передать экземпляр FormData
в xhr.send()
, я надеюсь, что также возможно заставить его работать с jQuery.
Update:
Я создал "билет функции" в jQuery Bug Tracker. Здесь: http://bugs.jquery.com/ticket/9995
Мне предложили использовать "предварительный фильтр Ajax"...
Update:
Во-первых, позвольте мне дать демонстрацию, демонстрирующую, какого поведения я бы хотел достичь.
HTML:
<form>
<input type="file" id="file" name="file">
<input type="submit">
</form>
JavaScript:
$( 'form' ).submit(function ( e ) {
var data, xhr;
data = new FormData();
data.append( 'file', $( '#file' )[0].files[0] );
xhr = new XMLHttpRequest();
xhr.open( 'POST', 'http://hacheck.tel.fer.hr/xml.pl', true );
xhr.onreadystatechange = function ( response ) {};
xhr.send( data );
e.preventDefault();
});
Приведенный выше код приводит к этому HTTP-запросу:
Это то, что мне нужно. Я хочу, чтобы этот тип контента "multipart/form-data" был
Предлагаемое решение будет таким:
$( 'form' ).submit(function ( e ) {
var data;
data = new FormData();
data.append( 'file', $( '#file' )[0].files[0] );
$.ajax({
url: 'http://hacheck.tel.fer.hr/xml.pl',
data: data,
processData: false,
type: 'POST',
success: function ( data ) {
alert( data );
}
});
e.preventDefault();
});
Однако это приводит к:
Как вы можете видеть, тип содержимого неверен...