javascript - working - xmlhttprequest загрузка файла




Как отправить объекты FormData с помощью Ajax-запросов в jQuery? (6)

JavaScript:

function submitForm() {
    var data1 = new FormData($('input[name^="file"]'));
    $.each($('input[name^="file"]')[0].files, function(i, file) {
        data1.append(i, file);
    });

    $.ajax({
        url: "<?php echo base_url() ?>employee/dashboard2/test2",
        type: "POST",
        data: data1,
        enctype: 'multipart/form-data',
        processData: false, // tell jQuery not to process the data
        contentType: false // tell jQuery not to set contentType
    }).done(function(data) {
        console.log("PHP Output:");
        console.log(data);
    });
    return false;
}

PHP:

public function upload_file() {
    foreach($_FILES as $key) {
        $name = time().$key['name'];
        $path = 'upload/'.$name;
        @move_uploaded_file($key['tmp_name'], $path);
    }
}

На этот вопрос уже есть ответ:

Стандарт XMLHttpRequest Level 2 (все еще рабочий проект) определяет интерфейс FormData . Этот интерфейс позволяет добавлять объекты File к XHR-запросам (Ajax-запросы).

Кстати, это новая функция - в прошлом использовался «скрытый-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 - 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 , по-видимому, несовместим.

Теперь, поскольку можно передать экземпляр FormData в xhr.send() , я надеюсь, что также возможно заставить его работать с jQuery.

Обновить:

Я создал «билет функции» в JQuery's Bug Tracker. Он находится здесь: http://bugs.jquery.com/ticket/9995

Мне предложили использовать «предварительный фильтр Ajax» ...

Обновить:

Во-первых, позвольте мне дать демонстрацию, демонстрирующую, какого поведения я бы хотел достичь.

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();
});

Однако это приводит к:

Как вы видите, тип контента неверен ...


Вместо - fd.append( 'userfile', $('#userfile')[0].files[0]);

Использовать - fd.append( 'file', $('#userfile')[0].files[0]);


Вы можете отправить объект FormData в ajax-запрос, используя следующий код,

$("form#formElement").submit(function(){
    var formData = new FormData($(this)[0]);
});

Это очень похоже на принятый ответ, но на фактический ответ на вопрос. Это автоматически представит элементы формы в FormData, и вам не нужно вручную добавлять данные в переменную FormData.

Метод ajax выглядит следующим образом:

$("form#formElement").submit(function(){
    var formData = new FormData($(this)[0]);
    //append some non-form data also
    formData.append('other_data',$("#someInputData").val());
    $.ajax({
        type: "POST",
        url: postDataUrl,
        data: formData,
        processData: false,
        contentType: false,
        dataType: "json",
        success: function(data, textStatus, jqXHR) {
           //process data
        },
        error: function(data, textStatus, jqXHR) {
           //process error msg
        },
});

Вы также можете вручную передать элемент формы внутри объекта FormData в качестве параметра, подобного этому

var formElem = $("#formId");
var formdata = new FormData(form[0]);

Надеюсь, поможет. ;)


Если вы хотите отправлять файлы с использованием ajax, используйте «jquery.form.js». Это легко передает все элементы формы.

Образцы http://jquery.malsup.com/form/#ajaxSubmit

приблизительный вид:

<form id='AddPhotoForm' method='post' action='../photo/admin_save_photo.php' enctype='multipart/form-data'>


<script type="text/javascript">
function showResponseAfterAddPhoto(responseText, statusText)
{ 
    information= responseText;
    callAjaxtolist();
    $("#AddPhotoForm").resetForm();
    $("#photo_msg").html('<div class="album_msg">Photo uploaded Successfully...</div>');        
};

$(document).ready(function(){
    $('.add_new_photo_div').live('click',function(){
            var options = {success:showResponseAfterAddPhoto};  
            $("#AddPhotoForm").ajaxSubmit(options);
        });
});
</script>


Я делаю это так, и это работает для меня, надеюсь, это поможет :)

   <div id="data">
        <form>
            <input type="file" name="userfile" id="userfile" size="20" />
            <br /><br />
            <input type="button" id="upload" value="upload" />
        </form>
    </div>
  <script>
        $(document).ready(function(){
                $('#upload').click(function(){

                    console.log('upload button clicked!')
                    var fd = new FormData();    
                    fd.append( 'userfile', $('#userfile')[0].files[0]);

                    $.ajax({
                      url: 'upload/do_upload',
                      data: fd,
                      processData: false,
                      contentType: false,
                      type: 'POST',
                      success: function(data){
                        console.log('upload success!')
                        $('#data').empty();
                        $('#data').append(data);

                      }
                    });
                });
        });
    </script>   




multipartform-data