So führen Sie das Hochladen von Dateien mithilfe der jquery-Serialisierung durch

83

Ich habe also ein Formular und sende das Formular über Ajax mithilfe der jquery-Serialisierungsfunktion

        serialized = $(Forms).serialize();

        $.ajax({

        type        : "POST",
        cache   : false,
        url     : "blah",
        data        : serialized,
        success: function(data) {

        }

Aber was ist, wenn das Formular ein <input type="file">Feld enthält? Wie übergebe ich die Datei mit dieser Ajax-Serialisierungsmethode in das Formular? Beim Drucken von $ _FILES wird nichts ausgegeben

kamikaze_pilot
quelle

Antworten:

53

Eine Datei kann nicht mit AJAX hochgeladen werden, da Sie nicht auf den Inhalt einer auf dem Clientcomputer gespeicherten Datei zugreifen und diese in der Anforderung mit Javascript senden können. Eine der Techniken, um dies zu erreichen, ist die Verwendung versteckter Iframes. Es gibt ein nettes JQuery-Formular-Plugin , mit dem Sie Ihre Formulare AJAXifizieren können und das auch das Hochladen von Dateien unterstützt . Wenn Sie dieses Plugin verwenden, sieht Ihr Code einfach so aus:

$(function() {
    $('#ifoftheform').ajaxForm(function(result) {
        alert('the form was successfully processed');
    });
});

Das Plugin kümmert sich automatisch darum, das submitEreignis des Formulars zu abonnieren , die Standardeinreichung abzubrechen, die Werte zu serialisieren, die richtige Methode zu verwenden und Felder zum Hochladen von Dateien zu verarbeiten, ...

Darin Dimitrov
quelle
42
Das stimmt nicht mehr. Mit einem <input type = 'file' name = 'myfile' /> und dem FormData () -Objekt kann eine Datei sehr einfach mit AJAX gespeichert werden. Siehe die Antwort von Silver89 unten.
Rook777
1
@ Rook777, das stimmt natürlich, wenn der von Ihnen verwendete Browser die HTML5-Datei-API unterstützt. Haben Sie dies im IE versucht, wie einfach es ist? Bis HTML5 zum Standard wird und von allen Browsern unterstützt wird, gibt es Plugins, da Sie mit AJAX keine Dateien hochladen können.
Darin Dimitrov
2
Du hast Recht. Ich habe das Glück, in einer Entwicklungsumgebung zu sein, die IE nicht unterstützt, also habe ich vergessen, darüber nachzudenken. Ja, ohne HTML5-Kompatibilität funktioniert diese Funktion nicht. Laut caniuse.com/xhr2 unterstützt diese Funktion bisher nur IE 10+.
Rook777
Das jQuery Form Plugin ist großartig!
user1570144
48

Verwenden Sie FormDataobject.It funktioniert für jede Art von Formular

$(document).on("submit", "form", function(event)
{
    event.preventDefault();
    $.ajax({
        url: $(this).attr("action"),
        type: $(this).attr("method"),
        dataType: "JSON",
        data: new FormData(this),
        processData: false,
        contentType: false,
        success: function (data, status)
        {

        },
        error: function (xhr, desc, err)
        {
            

        }
    });        

});
Shaiful Islam
quelle
Wichtiger Hinweis dazu: Wird processData: false, contentType: false,benötigt, um einen Illegal invocationFehler zu vermeiden , da jQuery ohne diese beim Senden versucht, die Formulardaten in eine Zeichenfolge zu konvertieren, was in diesem Fall nicht erwünscht ist.
Jeppe Mariager-Lam vor
23
   var form = $('#job-request-form')[0];
        var formData = new FormData(form);
        event.preventDefault();
        $.ajax({
            url: "/send_resume/", // the endpoint
            type: "POST", // http method
            processData: false,
            contentType: false,
            data: formData,

Es hat bei mir funktioniert! Setzen Sie einfach processData und contentType False.

Maryam Zakani
quelle
16

HTML

<form name="my_form" id="my_form" accept-charset="multipart/form-data" onsubmit="return false">
    <input id="name" name="name" placeholder="Enter Name" type="text" value="">
    <textarea id="detail" name="detail" placeholder="Enter Detail"></textarea>
    <select name="gender" id="gender">
        <option value="male" selected="selected">Male</option>
        <option value="female">Female</option>
    </select>
    <input type="file" id="my_images" name="my_images" multiple="" accept="image/x-png,image/gif,image/jpeg"/>
</form>

JavaScript

var data = new FormData();

//Form data
var form_data = $('#my_form').serializeArray();
$.each(form_data, function (key, input) {
    data.append(input.name, input.value);
});

//File data
var file_data = $('input[name="my_images"]')[0].files;
for (var i = 0; i < file_data.length; i++) {
    data.append("my_images[]", file_data[i]);
}

//Custom data
data.append('key', 'value');

$.ajax({
    url: "URL",
    method: "post",
    processData: false,
    contentType: false,
    data: data,
    success: function (data) {
        //success
    },
    error: function (e) {
        //error
    }
});

PHP

<?php
    echo '<pre>';
    print_r($_POST);
    print_r($_FILES);
    echo '</pre>';
    die();
?>
Renish Patel
quelle
Wie sende ich den Namen der Senden-Schaltfläche?
Muhammad Tarique
@ MuhammadTarique Sie fügen einfach eine Schaltfläche wie hinzu <button type="button" name="button_name" value="Contact Button">Submit</button>und Sie erhalten eine Antwort button_name = "Kontaktschaltfläche" auf der PHP-Seite
Renish Patel
Vielen Dank für Ihre Antwort, aber ich denke nicht, dass es so funktionieren wird. Allerdings habe ich dies bereits mitformData.append("btnName", "true");
Muhammad Tarique
@ MuhammadTarique Dieses Beispiel wurde bereits in diesem Beitrag hinzugefügt wiedata.append('key', 'value');
Renish Patel
11

Sie können Dateien über AJAX mithilfe der FormData-Methode hochladen. Obwohl IE7,8 und 9 die FormData-Funktionalität nicht unterstützen.

$.ajax({
    url: "ajax.php", 
    type: "POST",             
    data: new FormData('form'),
    contentType: false,       
    cache: false,             
    processData:false, 
    success: function(data) {
        $("#response").html(data);
    }
});
Rossco
quelle
Was ist 'Form' in neuen FormData ('Form'), ist es die ID, es funktioniert nicht für mich
Mohamed Selim
Ja, dies ist normalerweise die Formular-ID
Rossco
Für mich funktioniert es nur mit document.forms.form anstelle der 'form'-Zeichenfolge, die an den FormData-Konstruktor
Mohamed Selim - übergeben wird
10
$(document).on('click', '#submitBtn', function(e){
e.preventDefault();
e.stopImmediatePropagation();
var form = $("#myForm").closest("form");
var formData = new FormData(form[0]);
$.ajax({
    type: "POST",
    data: formData,
    dataType: "json",
    url: form.attr('action'),
    processData: false,
    contentType: false,
    success: function(data) {
         alert('Sucess! Form data posted with file type of input also!');
    }
)};});

Durch die Verwendung new FormData()und Einstellung processData: false, contentType:falsevon Ajax-Aufrufen funktionierte die Übermittlung des Formulars mit Dateieingabe für mich

Mit dem obigen Code kann ich Formulardaten mit Dateifeld auch über Ajax senden

RameshN
quelle
0

hmmmm ich denke, es gibt eine sehr effiziente Möglichkeit, es speziell für Leute zu machen, die alle Browser und nicht nur FormData ansprechen möchten unterstützte Browser

die Idee, IFRAME auf der Seite versteckt zu haben und eine normale Übermittlung für das Beispiel "From inside IFrame" vorzunehmen

<FORM action='save_upload.php' method=post
   enctype='multipart/form-data' target=hidden_upload>
   <DIV><input
      type=file name='upload_scn' class=file_upload></DIV>
   <INPUT
      type=submit name=submit value=Upload /> <IFRAME id=hidden_upload
      name=hidden_upload src='' onLoad='uploadDone("hidden_upload")'
      style='width:0;height:0;border:0px solid #fff'></IFRAME> 
</FORM>

Am wichtigsten ist es, ein Ziel der Form als versteckte Iframe- ID oder als Name und Enctype für mehrteilige / Formulardaten festzulegen , damit Fotos akzeptiert werden können

Javascript Seite

function getFrameByName(name) {
    for (var i = 0; i < frames.length; i++)
        if (frames[i].name == name)
            return frames[i];

    return null;
}

function uploadDone(name) {
    var frame = getFrameByName(name);
    if (frame) {
        ret = frame.document.getElementsByTagName("body")[0].innerHTML;

        if (ret.length) {
            var json = JSON.parse(ret);
         // do what ever you want 
        }
    }
}

serverseitiges Beispiel PHP

<?php
  $target_filepath = "/tmp/" . basename($_FILES['upload_scn']['name']);

  if (move_uploaded_file($_FILES['upload_scn']['tmp_name'], $target_filepath)) {
    $result = ....
  }

echo json_encode($result);
?>
Jehad Ahmad Jaghoub
quelle
0

HTML5 wird vorgestellt FormData Klasse ein, die zum Hochladen von Dateien mit Ajax verwendet werden kann.

Die FormData-Unterstützung beginnt mit den folgenden Versionen des Desktop-Browsers. IE 10+, Firefox 4.0+, Chrome 7+, Safari 5+, Opera 12+

FormData - Mozilla.org

Rahul Patel
quelle