570 Stimmen

Wie sendet man FormData-Objekte mit Ajax-Anfragen in jQuery?

El XMLHttpRequest Stufe 2 Standard (noch ein Arbeitsentwurf) definiert die FormData Schnittstelle. Diese Schnittstelle ermöglicht das Anhängen von File Objekte zu XHR-Anfragen (Ajax-Anfragen).

Dies ist übrigens eine neue Funktion - in der Vergangenheit wurde der "hidden-iframe-trick" verwendet (lesen Sie darüber in meine andere Frage ).

So funktioniert es (Beispiel):

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

donde input es un <input type="file"> Feld, und handler ist der Success-Handler für die Ajax-Anfrage.

Dies funktioniert in allen Browsern (wieder mit Ausnahme des IE) hervorragend.

Nun möchte ich diese Funktionalität mit jQuery zum Laufen bringen. Ich habe dies versucht:

var fd = new FormData();    
fd.append( 'file', input.files[0] );

$.post( 'http://example.com/script.php', fd, handler );

Leider funktioniert das nicht (es wird ein "Illegaler Aufruf"-Fehler ausgegeben - Screenshot ist hier ). Ich gehe davon aus, dass jQuery ein einfaches Key-Value-Objekt erwartet, das Formularfeld-Namen/Werte repräsentiert, und die FormData Instanz, die ich eingebe, ist offenbar nicht kompatibel.

Da es nun möglich ist, eine FormData Instanz in xhr.send() Ich hoffe, dass es auch möglich ist, es mit jQuery funktionieren zu lassen.


Aktualisierung:

Ich habe ein "Feature-Ticket" bei jQuery's Bug Tracker erstellt. Es ist hier: http://bugs.jquery.com/ticket/9995

Mir wurde vorgeschlagen, einen "Ajax-Vorfilter" zu verwenden...


Aktualisierung:

Lassen Sie mich zunächst anhand einer Demo zeigen, welches Verhalten ich erreichen möchte.

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

Der obige Code führt zu dieser HTTP-Anfrage:

multipartformdata

Das ist es, was ich brauche - Ich will den Inhaltstyp "multipart/form-data"!


Die vorgeschlagene Lösung würde folgendermaßen aussehen:

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

Dies führt jedoch zu:

wrongcontenttype

Wie Sie sehen können, ist der Inhaltstyp falsch...

4voto

dmnkhhn Punkte 1012

Sie können die $.ajax beforeSend Ereignis, um die Kopfzeile zu manipulieren.

beforeSend: function(xhr) { 
    xhr.setRequestHeader('Content-Type', 'multipart/form-data');
}

Unter diesem Link finden Sie weitere Informationen: http://msdn.microsoft.com/en-us/library/ms536752(v=vs.85).aspx

1voto

Rohit Punkte 165

Wenn Sie Dateien per Ajax übermitteln möchten, verwenden Sie "jquery.form.js". Damit lassen sich alle Formularelemente problemlos übermitteln.

Proben http://jquery.malsup.com/form/#ajaxSubmit

Grobansicht :

<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>

1voto

user4757231 Punkte 27

Anstelle von - fd.append( 'userfile', $('#userfile')[0].files[0]);

Verwendung - fd.append( 'file', $('#userfile')[0].files[0]);

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X