474 Stimmen

Hochladen von Daten und Dateien in einem Formular mit Ajax?

Ich benutze jQuery und Ajax für meine Formulare, um Daten und Dateien zu übermitteln, aber ich bin nicht sicher, wie man sowohl Daten als auch Dateien in einem Formular sendet?

Ich tue derzeit fast das Gleiche mit beiden Methoden, aber die Art und Weise, in der die Daten in einem Array gesammelt werden, ist anders, die Daten verwenden .serialize(); aber die Dateien verwenden = new FormData($(this)[0]);

Ist es möglich, beide Methoden zu kombinieren, um Dateien und Daten in einem Formular über Ajax hochladen zu können?

Daten jQuery, Ajax und html

$("form#data").submit(function(){

    var formData = $(this).serialize();

    $.ajax({
        url: window.location.pathname,
        type: 'POST',
        data: formData,
        async: false,
        success: function (data) {
            alert(data)
        },
        cache: false,
        contentType: false,
        processData: false
    });

    return false;
});

<form id="data" method="post">
    <input type="text" name="first" value="Bob" />
    <input type="text" name="middle" value="James" />
    <input type="text" name="last" value="Smith" />
    <button>Submit</button>
</form>

Dateien jQuery, Ajax und html

$("form#files").submit(function(){

    var formData = new FormData($(this)[0]);

    $.ajax({
        url: window.location.pathname,
        type: 'POST',
        data: formData,
        async: false,
        success: function (data) {
            alert(data)
        },
        cache: false,
        contentType: false,
        processData: false
    });

    return false;
});

<form id="files" method="post" enctype="multipart/form-data">
    <input name="image" type="file" />
    <button>Submit</button>
</form>

Wie kann ich die oben genannten Punkte kombinieren, so dass ich Daten und Dateien in einem Formular über Ajax senden kann?

Mein Ziel ist es, in der Lage sein, alle diese Form in einem Beitrag mit Ajax zu senden, ist es möglich?

<form id="datafiles" method="post" enctype="multipart/form-data">
    <input type="text" name="first" value="Bob" />
    <input type="text" name="middle" value="James" />
    <input type="text" name="last" value="Smith" />
    <input name="image" type="file" />
    <button>Submit</button>
</form>

537voto

Dan Punkte 11444

Das Problem, das ich hatte, war die Verwendung des falschen jQuery-Bezeichners.

Sie kann Daten und Dateien hochladen mit einem Formular Ajax verwenden .

PHP UND HTML

<?php

print_r($_POST);
print_r($_FILES);
?>

<form id="data" method="post" enctype="multipart/form-data">
    <input type="text" name="first" value="Bob" />
    <input type="text" name="middle" value="James" />
    <input type="text" name="last" value="Smith" />
    <input name="image" type="file" />
    <button>Submit</button>
</form>

jQuery + Ajax

$("form#data").submit(function(e) {
    e.preventDefault();    
    var formData = new FormData(this);

    $.ajax({
        url: window.location.pathname,
        type: 'POST',
        data: formData,
        success: function (data) {
            alert(data)
        },
        cache: false,
        contentType: false,
        processData: false
    });
});

Kurzfassung

$("form#data").submit(function(e) {
    e.preventDefault();
    var formData = new FormData(this);    

    $.post($(this).attr("action"), formData, function(data) {
        alert(data);
    });
});

34voto

Roey Punkte 1579

Eine andere Möglichkeit ist die Verwendung eines iframe und die Festlegung des Ziels des Formulars auf diesen.

können Sie dies versuchen (es verwendet jQuery):

function ajax_form($form, on_complete)
{
    var iframe;

    if (!$form.attr('target'))
    {
        //create a unique iframe for the form
        iframe = $("<iframe></iframe>").attr('name', 'ajax_form_' + Math.floor(Math.random() * 999999)).hide().appendTo($('body'));
        $form.attr('target', iframe.attr('name'));
    }

    if (on_complete)
    {
        iframe = iframe || $('iframe[name="' + $form.attr('target') + '"]');
        iframe.load(function ()
        {
            //get the server response
            var response = iframe.contents().find('body').text();
            on_complete(response);
        });
    }
}

es funktioniert mit allen Browsern, Sie müssen die Daten nicht serialisieren oder vorbereiten. Ein Nachteil ist, dass Sie den Fortschritt nicht überwachen können.

Außerdem erscheint die Anfrage, zumindest bei Chrome, nicht auf der Registerkarte "xhr" der Entwicklertools, sondern unter "doc".

30voto

h_power11 Punkte 333

Ich war mit diesem gleichen Problem in ASP.Net MVC mit HttpPostedFilebase und anstelle der Verwendung von Formular auf Submit ich brauchte, um Schaltfläche auf Klick zu verwenden, wo ich brauchte, um einige Sachen zu tun und dann, wenn alle OK das Formular einreichen, so hier ist, wie ich es arbeiten bekam

$(".submitbtn").on("click", function(e) {

    var form = $("#Form");

    // you can't pass Jquery form it has to be javascript form object
    var formData = new FormData(form[0]);

    //if you only need to upload files then 
    //Grab the File upload control and append each file manually to FormData
    //var files = form.find("#fileupload")[0].files;

    //$.each(files, function() {
    //  var file = $(this);
    //  formData.append(file[0].name, file[0]);
    //});

    if ($(form).valid()) {
        $.ajax({
            type: "POST",
            url: $(form).prop("action"),
            //dataType: 'json', //not sure but works for me without this
            data: formData,
            contentType: false, //this is requireded please see answers above
            processData: false, //this is requireded please see answers above
            //cache: false, //not sure but works for me without this
            error   : ErrorHandler,
            success : successHandler
        });
    }
});

dies wird dann korrekt bevölkern Ihr MVC-Modell, stellen Sie bitte sicher, in Ihrem Modell, die Eigenschaft für HttpPostedFileBase[] hat den gleichen Namen wie die Nombre der Eingabesteuerung in html, d.h.

<input id="fileupload" type="file" name="UploadedFiles" multiple>

public class MyViewModel
{
    public HttpPostedFileBase[] UploadedFiles { get; set; }
}

22voto

schaenk Punkte 247

Oder kürzer:

$("form#data").submit(function() {
    var formData = new FormData(this);
    $.post($(this).attr("action"), formData, function() {
        // success    
    });
    return false;
});

19voto

Adithya Upadhya Punkte 1849

EDIT: Mit der neuen Version von JQuery (3.6) können Sie auch versuchen, das Argument der Funktion contentType anstelle von enctype . Versuchen Sie contentType: multipart/form-data .


Für mich funktionierte es nicht ohne enctype: 'multipart/form-data' Feld in der Ajax-Anfrage. Ich hoffe, es hilft jemandem, der in einem ähnlichen Problem feststeckt.

Auch wenn die enctype wurde bereits im Formularattribut Aus irgendeinem Grund identifiziert die Ajax-Anfrage nicht automatisch die enctype ohne ausdrückliche Deklaration (jQuery 3.3.1).

// Tested, this works for me (jQuery 3.3.1)

fileUploadForm.submit(function (e) {   
    e.preventDefault();
    $.ajax({
            type: 'POST',
            url: $(this).attr('action'),
            enctype: 'multipart/form-data',
            data: new FormData(this),
            processData: false,
            contentType: false,
            success: function (data) {
                console.log('Thank God it worked!');
            }
        }
    );
});

// enctype field was set in the form but Ajax request didn't set it by default.

<form action="process/file-upload" enctype="multipart/form-data" method="post" >

     <input type="file" name="input-file" accept="text/plain" required> 
     ...
</form>

Wie bereits von anderen erwähnt, achten Sie bitte auch besonders auf die contentType y processData Felder.

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