web-dev-qa-db-fra.com

Télécharger à la fois des données et des fichiers sous une forme à l’aide de Ajax?

J'utilise jQuery et Ajax pour mes formulaires afin de soumettre des données et des fichiers, mais je ne sais pas comment envoyer des données et des fichiers dans un seul formulaire?

Je fais actuellement presque la même chose avec les deux méthodes, mais la façon dont les données sont rassemblées dans un tableau est différente, les données utilisent .serialize(); mais les fichiers utilisent = new FormData($(this)[0]);.

Est-il possible de combiner les deux méthodes pour pouvoir télécharger des fichiers et des données sous une forme unique via Ajax?

Data jQuery, Ajax et 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>

Fichiers jQuery, Ajax et 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>

Comment puis-je combiner ce qui précède pour pouvoir envoyer des données et des fichiers dans un seul formulaire via Ajax?

Mon but est de pouvoir envoyer tout ce formulaire en un seul message avec Ajax, est-ce possible?

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

Le problème que j'avais était d'utiliser le mauvais identifiant jQuery.

Vous pouvez télécharger des données et des fichiers avec un seul formulaire avec ajax .

PHP + 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
    });
});

Version courte

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

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

une autre option consiste à utiliser un iframe et à définir la cible du formulaire.

vous pouvez essayer ceci (il utilise 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);
        });
    }
}

cela fonctionne bien avec tous les navigateurs, vous n'avez pas besoin de sérialiser ou de préparer les données .. Un inconvénient est que vous ne pouvez pas surveiller les progrès.

aussi, au moins pour chrome, la demande n'apparaîtra pas dans l'onglet "xhr" des outils pour développeurs, mais sous "doc"

30
Roey

Ou plus court:

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

J'avais ce même problème dans ASP.Net MVC avec HttpPostedFilebase et au lieu d'utiliser le formulaire sur Submit, je devais utiliser le bouton sur lequel je devais faire des choses, puis si tout était bien le formulaire de soumission, voici comment je l'ai obtenu

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

ceci remplira correctement votre modèle MVC, veuillez vous assurer que, dans votre modèle, la propriété de HttpPostedFileBase [] a le même nom que le Nom du contrôle de saisie en HTML i.e.

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

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

Pour moi, cela ne fonctionnait pas sans le champ enctype: 'multipart/form-data' dans la requête Ajax. J'espère que cela aidera quelqu'un qui est coincé dans un problème similaire.

Même si la enctype était déjà définie dans l'attribut de formulaire , pour une raison quelconque, la demande Ajax n'a pas automatiquement identifié la enctype sans déclaration explicite (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>

Comme d'autres mentionnés ci-dessus, veuillez également porter une attention particulière aux champs contentType et processData.

0
Adithya Upadhya

Pour moi, le code suivant fonctionne 

  $(function () {
    debugger;
    document.getElementById("FormId").addEventListener("submit", function (e) {
        debugger;
        if (ValidDateFrom()) { // Check Validation 
            var form = e.target;
            if (form.getAttribute("enctype") === "multipart/form-data") {
                debugger;
                if (form.dataset.ajax) {
                    e.preventDefault();
                    e.stopImmediatePropagation();
                    var xhr = new XMLHttpRequest();
                    xhr.open(form.method, form.action);
                    xhr.onreadystatechange = function (result) {
                        debugger;
                        if (xhr.readyState == 4 && xhr.status == 200) {
                            debugger;
                            var responseData = JSON.parse(xhr.responseText);
                            SuccessMethod(responseData); // Redirect to your Success method 
                        }
                    };
                    xhr.send(new FormData(form));
                }
            }
        }
    }, true);
});

Dans votre méthode de post-action, transmettez le paramètre comme HttpPostedFileBase UploadFile et assurez-vous que l'entrée de fichier a les mêmes caractéristiques que celles mentionnées dans votre paramètre de la méthode d'action. Il devrait également fonctionner avec AJAX Begin form. 

Rappelez-vous ici que votre formulaire AJAX BEGIN ne fonctionnera pas ici puisque vous effectuez votre post call défini dans le code mentionné ci-dessus et que vous pouvez référencer votre méthode dans le code conformément à la condition requise.

Je sais que je réponds tard mais c'est ce qui a fonctionné pour moi

0
   <form id="form" method="post" action="otherpage.php" 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 type='button' id='submit_btn'>Submit</button>
</form>

<script>
 $(document).on("click","#submit_btn",function(e){  
     //Prevent Instant Click  
    e.preventDefault();
    // Create an FormData object 
        var formData =$("#form").submit(function(e){
            return ;
        });
      //formData[0] contain form data only 
      // You can directly make object via using form id but it require all ajax operation inside $("form").submit(<!-- Ajax Here   -->)
        var formData = new FormData(formData[0]);    
        $.ajax({
            url: $('#form').attr('action'),
            type: 'POST',
            data: formData,
            success: function(response) {console.log(response);},
            contentType: false,
            processData: false,
            cache: false
        });
        return false;
            });
</script>

///// otherpage.php

<?php
print_r($_FILES);
?>
0
Shailesh Dwivedi