Téléchargement de fichier jQuery Ajax

755

Puis-je utiliser le code jQuery suivant pour effectuer un téléchargement de fichier à l'aide de la méthode POST d'une demande ajax?

$.ajax({
    type: "POST",
    timeout: 50000,
    url: url,
    data: dataString,
    success: function (data) {
        alert('success');
        return false;
    }
});

Si c'est possible, dois-je remplir une datapartie? Est-ce la bonne façon? Je POSTE uniquement le fichier côté serveur.

J'ai fait des recherches sur Google, mais ce que j'ai trouvé était un plugin alors que dans mon plan, je ne veux pas l'utiliser. Du moins pour le moment.

Willy
la source
Ajax ne prend pas en charge les téléchargements de fichiers, vous devez utiliser iframe à la place
antyrat
1
Question connexe: stackoverflow.com/questions/6974684/…
Nathan Koop
2
Connexe: stackoverflow.com/questions/166221/…
Timo Huovinen

Réponses:

596

Le téléchargement de fichiers n'est pas possible via AJAX.
Vous pouvez télécharger un fichier sans actualiser la page en utilisant IFrame.
Vous pouvez vérifier plus de détails ici .


MISE À JOUR

Avec XHR2, le téléchargement de fichiers via AJAX est pris en charge. Par exemple via un FormDataobjet, mais malheureusement, il n'est pas pris en charge par tous les / anciens navigateurs.

FormData le support commence à partir des versions suivantes des navigateurs de bureau.

  • IE 10+
  • Firefox 4.0+
  • Chrome 7+
  • Safari 5+
  • Opera 12+

Pour plus de détails, voir le lien MDN .

Adeel
la source
41
Voici une liste des navigateurs spécifiques qui ne sont pas pris en charge: caniuse.com/#search=FormData Je n'ai pas non plus testé cela, mais voici un polyfill pour FormData gist.github.com/3120320
Ryan White
152
Plus précisément, IE <10 ne le fait pas, pour ceux qui sont trop paresseux pour lire le lien.
Kevin
22
@Synexis non, nous n'avons plus à attendre aussi longtemps car tous les IE n'ont que 22% de part de marché dans le monde et 27% aux États-Unis et baissent rapidement. Il y a de fortes chances que ce soient des personnes de plus de 70 ans. Donc, plutôt qu'IE dictant ce que les développeurs doivent faire, IE devra soit se mettre en forme, soit sortir de la course.
Drew Calder
30
@DrewCalder La plupart des utilisateurs d'IE sont des employés de bureau qui n'ont pas le choix du navigateur à utiliser en raison des politiques de l'entreprise. Je ne pense pas que l'âge y soit pour beaucoup. Je suppose que la plupart des gens> 70 obtiennent leur progéniture pour installer Chrome ou FF à la place :)
Nicolas Connault
3
Ce lien m'a vraiment aidé à comprendre le strict minimum. Je n'ai pas eu à utiliser de requête xhr. Si vous utilisez ajax, assurez-vous de le régler enctypesur "form/multipart"!
2015 lumineux
316

Les iframes ne sont plus nécessaires pour télécharger des fichiers via ajax. Je l'ai récemment fait moi-même. Consultez ces pages:

Utilisation de téléchargements de fichiers HTML5 avec AJAX et jQuery

http://dev.w3.org/2006/webapi/FileAPI/#FileReader-interface

Mis à jour la réponse et nettoyé. Utilisez la fonction getSize pour vérifier la taille ou utilisez la fonction getType pour vérifier les types. Ajout du code html et css de la barre de progression.

var Upload = function (file) {
    this.file = file;
};

Upload.prototype.getType = function() {
    return this.file.type;
};
Upload.prototype.getSize = function() {
    return this.file.size;
};
Upload.prototype.getName = function() {
    return this.file.name;
};
Upload.prototype.doUpload = function () {
    var that = this;
    var formData = new FormData();

    // add assoc key values, this will be posts values
    formData.append("file", this.file, this.getName());
    formData.append("upload_file", true);

    $.ajax({
        type: "POST",
        url: "script",
        xhr: function () {
            var myXhr = $.ajaxSettings.xhr();
            if (myXhr.upload) {
                myXhr.upload.addEventListener('progress', that.progressHandling, false);
            }
            return myXhr;
        },
        success: function (data) {
            // your callback here
        },
        error: function (error) {
            // handle error
        },
        async: true,
        data: formData,
        cache: false,
        contentType: false,
        processData: false,
        timeout: 60000
    });
};

Upload.prototype.progressHandling = function (event) {
    var percent = 0;
    var position = event.loaded || event.position;
    var total = event.total;
    var progress_bar_id = "#progress-wrp";
    if (event.lengthComputable) {
        percent = Math.ceil(position / total * 100);
    }
    // update progressbars classes so it fits your code
    $(progress_bar_id + " .progress-bar").css("width", +percent + "%");
    $(progress_bar_id + " .status").text(percent + "%");
};

Comment utiliser la classe Upload

//Change id to your id
$("#ingredient_file").on("change", function (e) {
    var file = $(this)[0].files[0];
    var upload = new Upload(file);

    // maby check size or type here with upload.getSize() and upload.getType()

    // execute upload
    upload.doUpload();
});

Code HTML de la barre de progression

<div id="progress-wrp">
    <div class="progress-bar"></div>
    <div class="status">0%</div>
</div>

Code CSS de la barre de progression

#progress-wrp {
  border: 1px solid #0099CC;
  padding: 1px;
  position: relative;
  height: 30px;
  border-radius: 3px;
  margin: 10px;
  text-align: left;
  background: #fff;
  box-shadow: inset 1px 3px 6px rgba(0, 0, 0, 0.12);
}

#progress-wrp .progress-bar {
  height: 100%;
  border-radius: 3px;
  background-color: #f39ac7;
  width: 0;
  box-shadow: inset 1px 1px 10px rgba(0, 0, 0, 0.11);
}

#progress-wrp .status {
  top: 3px;
  left: 50%;
  position: absolute;
  display: inline-block;
  color: #000000;
}
Ziinloader
la source
3
Vous pouvez plus ou moins copier le code directement et l'utiliser. Modifiez simplement quelques noms d'ID et noms de classe. Toute personnalisation est à vous.
Ziinloader
4
Notez que myXhr semble être global ainsi que le nom, la taille et le type. Il est également préférable d'utiliser "beforeSend" pour augmenter l'objet XMLHttpRequest déjà créé plutôt que d'utiliser "xhr" pour en créer un puis le modifier.
awatts
8
Je ne pense pas que nous puissions l'utiliser comme c'est @Ziinloader. Vous utilisez une méthode locale qui n'est pas inclus: writer(catchFile). Qu'est-ce que c'est writer()?
tandrewnichols
4
Que faire si les données contiennent également quelques champs avec le fichier à télécharger?
raju
2
@Ziinloader Ceci est un exemple extrêmement utile que je vois que vous êtes revenu à plusieurs reprises. Vraiment une réponse qui vaut bien plus que le seul vote positif que je puisse donner.
Regular Joe
191

La publication et le téléchargement de fichiers Ajax sont possibles. J'utilise la jQuery $.ajaxfonction pour charger mes fichiers. J'ai essayé d'utiliser l'objet XHR mais je n'ai pas pu obtenir de résultats côté serveur avec PHP.

var formData = new FormData();
formData.append('file', $('#file')[0].files[0]);

$.ajax({
       url : 'upload.php',
       type : 'POST',
       data : formData,
       processData: false,  // tell jQuery not to process the data
       contentType: false,  // tell jQuery not to set contentType
       success : function(data) {
           console.log(data);
           alert(data);
       }
});

Comme vous pouvez le voir, vous devez créer un objet FormData, vide ou à partir de (sérialisé? - $('#yourForm').serialize())formulaire existant, puis attacher le fichier d'entrée.

Voici plus d'informations: - Comment télécharger un fichier à l'aide de jQuery.ajax et FormData - Téléchargement de fichiers via jQuery, l'objet FormData est fourni et aucun nom de fichier, demande GET

Pour le processus PHP, vous pouvez utiliser quelque chose comme ceci:

//print_r($_FILES);
$fileName = $_FILES['file']['name'];
$fileType = $_FILES['file']['type'];
$fileError = $_FILES['file']['error'];
$fileContent = file_get_contents($_FILES['file']['tmp_name']);

if($fileError == UPLOAD_ERR_OK){
   //Processes your file here
}else{
   switch($fileError){
     case UPLOAD_ERR_INI_SIZE:   
          $message = 'Error al intentar subir un archivo que excede el tamaño permitido.';
          break;
     case UPLOAD_ERR_FORM_SIZE:  
          $message = 'Error al intentar subir un archivo que excede el tamaño permitido.';
          break;
     case UPLOAD_ERR_PARTIAL:    
          $message = 'Error: no terminó la acción de subir el archivo.';
          break;
     case UPLOAD_ERR_NO_FILE:    
          $message = 'Error: ningún archivo fue subido.';
          break;
     case UPLOAD_ERR_NO_TMP_DIR: 
          $message = 'Error: servidor no configurado para carga de archivos.';
          break;
     case UPLOAD_ERR_CANT_WRITE: 
          $message= 'Error: posible falla al grabar el archivo.';
          break;
     case  UPLOAD_ERR_EXTENSION: 
          $message = 'Error: carga de archivo no completada.';
          break;
     default: $message = 'Error: carga de archivo no completada.';
              break;
    }
      echo json_encode(array(
               'error' => true,
               'message' => $message
            ));
}
pedrozopayares
la source
2
Quelle bibliothèque jquery dois-je référencer pour exécuter ce code?
Rayden Black
La réponse a été écrite en 2014. La version de JQuery était 1.10. Je n'ai pas essayé avec des versions plus récentes.
pedrozopayares
5
formData.append('file', $('#file')[0].files[0]);revient undefinedet console.log(formData) n'a rien sauf_proto_
Yakob Ubaidi
1
Non pris en charge par IE 9, au cas où certains
seraient
3
Je l'ai fait fonctionner ... Pincez-moi, je suis sur le fichier jQuery Ajax upload paradis! var formData = new FormData(); formData.append('file', document.getElementById('file').files[0]); $.ajax({ url : $("form[name='uploadPhoto']").attr("action"), type : 'POST', data : formData, processData: false, // tell jQuery not to process the data contentType: false, // tell jQuery not to set contentType success : function(data) { console.log(data); alert(data); } });
TARKUS
104

Formulaire de téléchargement simple

 <script>
   //form Submit
   $("form").submit(function(evt){	 
      evt.preventDefault();
      var formData = new FormData($(this)[0]);
   $.ajax({
       url: 'fileUpload',
       type: 'POST',
       data: formData,
       async: false,
       cache: false,
       contentType: false,
       enctype: 'multipart/form-data',
       processData: false,
       success: function (response) {
         alert(response);
       }
   });
   return false;
 });
</script>
<!--Upload Form-->
<form>
  <table>
    <tr>
      <td colspan="2">File Upload</td>
    </tr>
    <tr>
      <th>Select File </th>
      <td><input id="csv" name="csv" type="file" /></td>
    </tr>
    <tr>
      <td colspan="2">
        <input type="submit" value="submit"/> 
      </td>
    </tr>
  </table>
</form>

vickisys
la source
monsieur quels sont les js qui ont été utilisés sur cet exemple y a-t-il un plugin jquery spécifique pour celui-ci ... j'ai une question qui m'a été posée ici pouvez-vous s'il vous plaît vérifier ma question .. je veux télécharger plusieurs fichiers ou images dans ce projet ici est le lien stackoverflow.com/questions/28644200/…
Brownman Revival
19
$ (this) [0] est- ce
machineaddict
2
Quel est le paramètre sur le serveur pour le fichier publié? Pouvez-vous s'il vous plaît poster une partie serveur.
FrenkyB
@FrenkyB et autres - les fichiers sur le serveur (en PHP) ne sont pas stockés dans la variable $ _POST - ils sont stockés dans la variable $ _FILES. Dans ce cas, vous y accéderez avec $ _FILES ["csv"] car "csv" est l'attribut de nom de la balise d'entrée.
dev_masta
68

Je suis assez en retard pour cela, mais je cherchais une solution de téléchargement d'images basée sur ajax et la réponse que je cherchais était un peu dispersée dans cet article. La solution que j'ai choisie impliquait l'objet FormData. J'ai assemblé une forme de base du code que j'ai mis en place. Vous pouvez voir qu'il montre comment ajouter un champ personnalisé au formulaire avec fd.append () ainsi que comment gérer les données de réponse lorsque la demande ajax est effectuée.

Importer du HTML:

<!DOCTYPE html>
<html>
<head>
    <title>Image Upload Form</title>
    <script src="//code.jquery.com/jquery-1.9.1.js"></script>
    <script type="text/javascript">
        function submitForm() {
            console.log("submit event");
            var fd = new FormData(document.getElementById("fileinfo"));
            fd.append("label", "WEBUPLOAD");
            $.ajax({
              url: "upload.php",
              type: "POST",
              data: fd,
              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;
        }
    </script>
</head>

<body>
    <form method="post" id="fileinfo" name="fileinfo" onsubmit="return submitForm();">
        <label>Select a file:</label><br>
        <input type="file" name="file" required />
        <input type="submit" value="Upload" />
    </form>
    <div id="output"></div>
</body>
</html>

Dans le cas où vous travaillez avec php, voici un moyen de gérer le téléchargement qui comprend l'utilisation des deux champs personnalisés illustrés dans le code HTML ci-dessus.

Upload.php

<?php
if ($_POST["label"]) {
    $label = $_POST["label"];
}
$allowedExts = array("gif", "jpeg", "jpg", "png");
$temp = explode(".", $_FILES["file"]["name"]);
$extension = end($temp);
if ((($_FILES["file"]["type"] == "image/gif")
|| ($_FILES["file"]["type"] == "image/jpeg")
|| ($_FILES["file"]["type"] == "image/jpg")
|| ($_FILES["file"]["type"] == "image/pjpeg")
|| ($_FILES["file"]["type"] == "image/x-png")
|| ($_FILES["file"]["type"] == "image/png"))
&& ($_FILES["file"]["size"] < 200000)
&& in_array($extension, $allowedExts)) {
    if ($_FILES["file"]["error"] > 0) {
        echo "Return Code: " . $_FILES["file"]["error"] . "<br>";
    } else {
        $filename = $label.$_FILES["file"]["name"];
        echo "Upload: " . $_FILES["file"]["name"] . "<br>";
        echo "Type: " . $_FILES["file"]["type"] . "<br>";
        echo "Size: " . ($_FILES["file"]["size"] / 1024) . " kB<br>";
        echo "Temp file: " . $_FILES["file"]["tmp_name"] . "<br>";

        if (file_exists("uploads/" . $filename)) {
            echo $filename . " already exists. ";
        } else {
            move_uploaded_file($_FILES["file"]["tmp_name"],
            "uploads/" . $filename);
            echo "Stored in: " . "uploads/" . $filename;
        }
    }
} else {
    echo "Invalid file";
}
?>
lee8oi
la source
je Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https,comprends pourquoi est-ce si monsieur que je copie coller votre code tel qu'il est
Brownman Revival
2
@HogRider - si vous Google votre message d'erreur, c'est le premier résultat: stackoverflow.com/questions/10752055/… Accédez -vous à vos pages Web localement via file://, plutôt que d'utiliser un serveur Web? En passant, il n'est pas recommandé de simplement copier-coller du code à l'aveugle sans d'abord le comprendre. Je vous recommande de parcourir le code ligne par ligne pour comprendre ce qui se passe avant d'utiliser le code.
colincameron
@colincameron merci de clarifier certaines choses que j'ai parcourues ligne par ligne et je ne comprends pas vraiment beaucoup alors j'ai posé la question afin que quelqu'un puisse clarifier mes doutes. J'utilise local par voie xampp pour être exact. Puis-je poser une question que vous pourriez peut-être clarifier?
Brownman Revival
@Brownman Revival: Je sais que c'est trop tard pour la réponse .. Vous avez obtenu une erreur d'origine croisée car vous avez ouvert le fichier html en tant que fichier plutôt que de l'exécuter à partir du serveur.
Adarsh ​​Mohan
@AdarshMohan j'apprécie la réponse comment suggérez-vous que je le fasse pour bien faire les choses?
Brownman Revival
31

Un téléchargement AJAX est en effet possible avec XMLHttpRequest(). Aucun iframes nécessaire. La progression du téléchargement peut être affichée.

Pour plus de détails, voir: Répondre à https://stackoverflow.com/a/4943774/873282 à la question progression du téléchargement jQuery et le téléchargement du fichier AJAX .

koppor
la source
24
Malheureusement, IE <10 ne prend pas cela en charge.
Sasha Chedygov
1
Lorsque vous souhaitez simplement faire référence à une autre page comme réponse, vous pouvez voter pour fermer en tant que dupkucate ou laisser un commentaire sous la question. Ce message n'est pas une réponse. Un message de ce genre ressemble à une tentative d'agriculteur.
mickmackusa
18

Voici comment je l'ai fait fonctionner:

HTML

<input type="file" id="file">
<button id='process-file-button'>Process</button>

JS

$('#process-file-button').on('click', function (e) {
    let files = new FormData(), // you can consider this as 'data bag'
        url = 'yourUrl';

    files.append('fileName', $('#file')[0].files[0]); // append selected file to the bag named 'file'

    $.ajax({
        type: 'post',
        url: url,
        processData: false,
        contentType: false,
        data: files,
        success: function (response) {
            console.log(response);
        },
        error: function (err) {
            console.log(err);
        }
    });
});

PHP

if (isset($_FILES) && !empty($_FILES)) {
    $file = $_FILES['fileName'];
    $name = $file['name'];
    $path = $file['tmp_name'];


    // process your file

}
М.Б.
la source
2
Ce qui m'a le plus aidé à ce sujet, c'est la $('#file')[0].files[0]forme d'une étrange solution de contournement JS sans nécessiter une bonne<form>
ffgpga08
C'est la solution complète, le bit PHP aide aussi.
cdsaenz
14

Au cas où vous voudriez le faire comme ça:

$.upload( form.action, new FormData( myForm))
.progress( function( progressEvent, upload) {
    if( progressEvent.lengthComputable) {
        var percent = Math.round( progressEvent.loaded * 100 / progressEvent.total) + '%';
        if( upload) {
            console.log( percent + ' uploaded');
        } else {
            console.log( percent + ' downloaded');
        }
    }
})
.done( function() {
    console.log( 'Finished upload');                    
});

que

https://github.com/lgersman/jquery.orangevolt-ampere/blob/master/src/jquery.upload.js

pourrait être votre solution.

lgersman
la source
Où est la méthode de téléchargement dans $ object, le lien ci-dessus n'existe pas
coolesting
2
Merci d'avoir posté votre réponse! Veuillez lire attentivement la FAQ sur l' autopromotion. Notez également qu'il est nécessaire que vous publiez un avertissement chaque fois que vous vous connectez à votre propre site / produit.
Andrew Barber le
13
  • Utilisez un iframe caché et définissez la cible de votre formulaire sur le nom de cet iframe. De cette façon, lorsque le formulaire est soumis, seule l'iframe sera actualisée.
  • Avoir un gestionnaire d'événements enregistré pour l'événement de chargement de l'iframe pour analyser la réponse.

Plus de détails sur mon article de blog: http://blog.manki.in/2011/08/ajax-fie-upload.html .

Manki
la source
Évitez les iframes dans la mesure du possible
Bhargav Nanekalva
@BhargavNanekalva quelle est votre préoccupation?
aswzen
13
$("#submit_car").click( function() {
  var formData = new FormData($('#car_cost_form')[0]);
$.ajax({
       url: 'car_costs.php',
       data: formData,
       async: false,
       contentType: false,
       processData: false,
       cache: false,
       type: 'POST',
       success: function(data)
       {
       },
     })    return false;    
});

modifier: noter le type de contenu et les données de processus Vous pouvez simplement l'utiliser pour télécharger des fichiers via Ajax ...... soumettre l'entrée ne peut pas être en dehors de l'élément de formulaire :)

Gvice
la source
3
En utilisant cette méthode, vous pouvez publier un formulaire mais pas avec des champs de type «fichier». Cette question concerne spécifiquement le téléchargement de fichiers.
Jomy John
11

Mise à jour 2019:

html

<form class="fr" method='POST' enctype="multipart/form-data"> {% csrf_token %}
<textarea name='text'>
<input name='example_image'>
<button type="submit">
</form>

js

$(document).on('submit', '.fr', function(){

    $.ajax({ 
        type: 'post', 
        url: url, <--- you insert proper URL path to call your views.py function here.
        enctype: 'multipart/form-data',
        processData: false,
        contentType: false,
        data: new FormData(this) ,
        success: function(data) {
             console.log(data);
        }
        });
        return false;

    });

views.py

form = ThisForm(request.POST, request.FILES)

if form.is_valid():
    text = form.cleaned_data.get("text")
    example_image = request.FILES['example_image']
Geai
la source
1
Comment cela améliore-t-il l'une des réponses déjà données? Cette réponse mentionne également un fichier views.py qui est Django et n'a rien à voir avec la question.
dirkgroten
6
Parce que le problème se manifeste de manière comparable lors de l'utilisation de Django, et si vous utilisez Django, il n'y a pas beaucoup de directives ici pour le résoudre. Je pensais offrir une assistance proactive au cas où quelqu'un arriverait ici comme je l'ai fait à l'avenir. Vous avez une dure journée?
Jay
9

Utilisez FormData. Ça marche vraiment bien :-) ...

var jform = new FormData();
jform.append('user',$('#user').val());
jform.append('image',$('#image').get(0).files[0]); // Here's the important bit

$.ajax({
    url: '/your-form-processing-page-url-here',
    type: 'POST',
    data: jform,
    dataType: 'json',
    mimeType: 'multipart/form-data', // this too
    contentType: false,
    cache: false,
    processData: false,
    success: function(data, status, jqXHR){
        alert('Hooray! All is well.');
        console.log(data);
        console.log(status);
        console.log(jqXHR);

    },
    error: function(jqXHR,status,error){
        // Hopefully we should never reach here
        console.log(jqXHR);
        console.log(status);
        console.log(error);
    }
});
delboy1978uk
la source
voici ce que: ('utilisateur', $ ('# utilisateur'). val ());
rahim.nagori
la zone de texte avec id = "utilisateur" est ajoutée au formulaire @ rahim.nagori
Alp Altunel
1
Une approche plus directe: var jform = new FormData ($ ('form'). Get (0));
André Morales il y a
agréable, merci, j'essaierai la prochaine fois que j'utilise FormData
delboy1978uk
7

J'ai mis en place une sélection de fichiers multiples avec prévisualisation et téléchargement instantanés après avoir supprimé les fichiers indésirables de l'aperçu via ajax.

Une documentation détaillée peut être trouvée ici: http://anasthecoder.blogspot.ae/2014/12/multi-file-select-preview-without.html

Démo: http://jsfiddle.net/anas/6v8Kz/7/embedded/result/

jsFiddle: http://jsfiddle.net/anas/6v8Kz/7/

Javascript:

    $(document).ready(function(){
    $('form').submit(function(ev){
        $('.overlay').show();
        $(window).scrollTop(0);
        return upload_images_selected(ev, ev.target);
    })
})
function add_new_file_uploader(addBtn) {
    var currentRow = $(addBtn).parent().parent();
    var newRow = $(currentRow).clone();
    $(newRow).find('.previewImage, .imagePreviewTable').hide();
    $(newRow).find('.removeButton').show();
    $(newRow).find('table.imagePreviewTable').find('tr').remove();
    $(newRow).find('input.multipleImageFileInput').val('');
    $(addBtn).parent().parent().parent().append(newRow);
}

function remove_file_uploader(removeBtn) {
    $(removeBtn).parent().parent().remove();
}

function show_image_preview(file_selector) {
    //files selected using current file selector
    var files = file_selector.files;
    //Container of image previews
    var imageContainer = $(file_selector).next('table.imagePreviewTable');
    //Number of images selected
    var number_of_images = files.length;
    //Build image preview row
    var imagePreviewRow = $('<tr class="imagePreviewRow_0"><td valign=top style="width: 510px;"></td>' +
        '<td valign=top><input type="button" value="X" title="Remove Image" class="removeImageButton" imageIndex="0" onclick="remove_selected_image(this)" /></td>' +
        '</tr> ');
    //Add image preview row
    $(imageContainer).html(imagePreviewRow);
    if (number_of_images > 1) {
        for (var i =1; i<number_of_images; i++) {
            /**
             *Generate class name of the respective image container appending index of selected images, 
             *sothat we can match images selected and the one which is previewed
             */
            var newImagePreviewRow = $(imagePreviewRow).clone().removeClass('imagePreviewRow_0').addClass('imagePreviewRow_'+i);
            $(newImagePreviewRow).find('input[type="button"]').attr('imageIndex', i);
            $(imageContainer).append(newImagePreviewRow);
        }
    }
    for (var i = 0; i < files.length; i++) {
        var file = files[i];
        /**
         * Allow only images
         */
        var imageType = /image.*/;
        if (!file.type.match(imageType)) {
          continue;
        }

        /**
         * Create an image dom object dynamically
         */
        var img = document.createElement("img");

        /**
         * Get preview area of the image
         */
        var preview = $(imageContainer).find('tr.imagePreviewRow_'+i).find('td:first');

        /**
         * Append preview of selected image to the corresponding container
         */
        preview.append(img); 

        /**
         * Set style of appended preview(Can be done via css also)
         */
        preview.find('img').addClass('previewImage').css({'max-width': '500px', 'max-height': '500px'});

        /**
         * Initialize file reader
         */
        var reader = new FileReader();
        /**
         * Onload event of file reader assign target image to the preview
         */
        reader.onload = (function(aImg) { return function(e) { aImg.src = e.target.result; }; })(img);
        /**
         * Initiate read
         */
        reader.readAsDataURL(file);
    }
    /**
     * Show preview
     */
    $(imageContainer).show();
}

function remove_selected_image(close_button)
{
    /**
     * Remove this image from preview
     */
    var imageIndex = $(close_button).attr('imageindex');
    $(close_button).parents('.imagePreviewRow_' + imageIndex).remove();
}

function upload_images_selected(event, formObj)
{
    event.preventDefault();
    //Get number of images
    var imageCount = $('.previewImage').length;
    //Get all multi select inputs
    var fileInputs = document.querySelectorAll('.multipleImageFileInput');
    //Url where the image is to be uploaded
    var url= "/upload-directory/";
    //Get number of inputs
    var number_of_inputs = $(fileInputs).length; 
    var inputCount = 0;

    //Iterate through each file selector input
    $(fileInputs).each(function(index, input){

        fileList = input.files;
        // Create a new FormData object.
        var formData = new FormData();
        //Extra parameters can be added to the form data object
        formData.append('bulk_upload', '1');
        formData.append('username', $('input[name="username"]').val());
        //Iterate throug each images selected by each file selector and find if the image is present in the preview
        for (var i = 0; i < fileList.length; i++) {
            if ($(input).next('.imagePreviewTable').find('.imagePreviewRow_'+i).length != 0) {
                var file = fileList[i];
                // Check the file type.
                if (!file.type.match('image.*')) {
                    continue;
                }
                // Add the file to the request.
                formData.append('image_uploader_multiple[' +(inputCount++)+ ']', file, file.name);
            }
        }
        // Set up the request.
        var xhr = new XMLHttpRequest();
        xhr.open('POST', url, true);
        xhr.onload = function () {
            if (xhr.status === 200) {
                var jsonResponse = JSON.parse(xhr.responseText);
                if (jsonResponse.status == 1) {
                    $(jsonResponse.file_info).each(function(){
                        //Iterate through response and find data corresponding to each file uploaded
                        var uploaded_file_name = this.original;
                        var saved_file_name = this.target;
                        var file_name_input = '<input type="hidden" class="image_name" name="image_names[]" value="' +saved_file_name+ '" />';
                        file_info_container.append(file_name_input);

                        imageCount--;
                    })
                    //Decrement count of inputs to find all images selected by all multi select are uploaded
                    number_of_inputs--;
                    if(number_of_inputs == 0) {
                        //All images selected by each file selector is uploaded
                        //Do necessary acteion post upload
                        $('.overlay').hide();
                    }
                } else {
                    if (typeof jsonResponse.error_field_name != 'undefined') {
                        //Do appropriate error action
                    } else {
                        alert(jsonResponse.message);
                    }
                    $('.overlay').hide();
                    event.preventDefault();
                    return false;
                }
            } else {
                /*alert('Something went wrong!');*/
                $('.overlay').hide();
                event.preventDefault();
            }
        };
        xhr.send(formData);
    })

    return false;
}
Ima
la source
@Bhargav: Veuillez consulter le blog pour des explications: goo.gl/umgFFy . Si vous avez encore des questions, revenez à moi Merci
Ima
7

Je les ai traités dans un code simple. Vous pouvez télécharger une démo fonctionnelle à partir d' ici

Pour votre cas, c'est très possible. Je vais vous expliquer étape par étape comment vous pouvez télécharger un fichier sur le serveur en utilisant AJAX jquery.

Commençons par créer un fichier HTML pour ajouter l'élément de fichier de formulaire suivant, comme indiqué ci-dessous.

<form action="" id="formContent" method="post" enctype="multipart/form-data" >
         <input  type="file" name="file"  required id="upload">
         <button class="submitI" >Upload Image</button> 
</form>

Ensuite, créez un fichier jquery.js et ajoutez le code suivant pour gérer notre soumission de fichier au serveur

    $("#formContent").submit(function(e){
        e.preventDefault();

    var formdata = new FormData(this);

        $.ajax({
            url: "ajax_upload_image.php",
            type: "POST",
            data: formdata,
            mimeTypes:"multipart/form-data",
            contentType: false,
            cache: false,
            processData: false,
            success: function(){
                alert("file successfully submitted");
            },error: function(){
                alert("okey");
            }
         });
      });
    });

Voilà. Voir plus

Daniel Nyamasyo
la source
7

L'utilisation de FormData est la voie à suivre comme l'indiquent de nombreuses réponses. voici un peu de code qui fonctionne très bien à cet effet. Je suis également d'accord avec le commentaire d'imbriquer des blocs ajax pour compléter des circonstances complexes. En incluant e.PreventDefault (); d'après mon expérience, le code est plus compatible avec tous les navigateurs.

    $('#UploadB1').click(function(e){        
    e.preventDefault();

    if (!fileupload.valid()) {
        return false;            
    }

    var myformData = new FormData();        
    myformData.append('file', $('#uploadFile')[0].files[0]);

    $("#UpdateMessage5").html("Uploading file ....");
    $("#UpdateMessage5").css("background","url(../include/images/loaderIcon.gif) no-repeat right");

    myformData.append('mode', 'fileUpload');
    myformData.append('myid', $('#myid').val());
    myformData.append('type', $('#fileType').val());
    //formData.append('myfile', file, file.name); 

    $.ajax({
        url: 'include/fetch.php',
        method: 'post',
        processData: false,
        contentType: false,
        cache: false,
        data: myformData,
        enctype: 'multipart/form-data',
        success: function(response){
            $("#UpdateMessage5").html(response); //.delay(2000).hide(1); 
            $("#UpdateMessage5").css("background","");

            console.log("file successfully submitted");
        },error: function(){
            console.log("not okay");
        }
    });
});
Mike Volmar
la source
cela exécute le formulaire via jquery validate ... if (! fileupload.valid ()) {return false; }
Mike Volmar
7

Utiliser du js pur c'est plus facile

async function saveFile(inp) 
{
    let formData = new FormData();           
    formData.append("file", inp.files[0]);
    await fetch('/upload/somedata', {method: "POST", body: formData});    
    alert('success');
}
<input type="file" onchange="saveFile(this)" >

  • Côté serveur, vous pouvez lire le nom du fichier d'origine (et d'autres informations) qui est automatiquement inclus pour la demande.
  • Vous n'avez PAS besoin de définir l'en-tête "Content-Type" sur "multipart / form-data" le navigateur le définira automatiquement
  • Ces solutions devraient fonctionner sur tous les principaux navigateurs.

Voici un extrait plus développé avec gestion des erreurs et envoi json supplémentaire

Kamil Kiełczewski
la source
6

Oui, vous pouvez simplement utiliser javascript pour obtenir le fichier, en vous assurant de lire le fichier en tant qu'URL de données. Analyser le contenu avant base64 pour obtenir réellement les données encodées en base 64, puis si vous utilisez php ou vraiment n'importe quel langage d'arrière-plan, vous pouvez décoder les données en base 64 et les enregistrer dans un fichier comme indiqué ci-dessous

Javascript:
var reader = new FileReader();
reader.onloadend = function ()
{
  dataToBeSent = reader.result.split("base64,")[1];
  $.post(url, {data:dataToBeSent});
}
reader.readAsDataURL(this.files[0]);


PHP:
    file_put_contents('my.pdf', base64_decode($_POST["data"]));

Bien sûr, vous voudrez probablement faire une validation comme vérifier le type de fichier avec lequel vous traitez et des trucs comme ça, mais c'est l'idée.

Piacenti
la source
file_put_contents ($ fname, file_get_contents ($ _ POST ['data'])); file_get_contents traite du décodage et des données: // header
Nande
5
<html>
    <head>
        <title>Ajax file upload</title>
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
        <script>
            $(document).ready(function (e) {
            $("#uploadimage").on('submit', (function(e) {
            e.preventDefault();
                    $.ajax({
                    url: "upload.php", // Url to which the request is send
                            type: "POST", // Type of request to be send, called as method
                            data: new FormData(this), // Data sent to server, a set of key/value pairs (i.e. form fields and values)
                            contentType: false, // The content type used when sending data to the server.
                            cache: false, // To unable request pages to be cached
                            processData:false, // To send DOMDocument or non processed data file it is set to false
                            success: function(data)   // A function to be called if request succeeds
                            {
                            alert(data);
                            }
                    });
            }));
        </script>
    </head>
    <body>
        <div class="main">
            <h1>Ajax Image Upload</h1><br/>
            <hr>
            <form id="uploadimage" action="" method="post" enctype="multipart/form-data">
                <div id="image_preview"><img id="previewing" src="noimage.png" /></div>
                <hr id="line">
                <div id="selectImage">
                    <label>Select Your Image</label><br/>
                    <input type="file" name="file" id="file" required />
                    <input type="submit" value="Upload" class="submit" />
                </div>
            </form>
        </div>
    </body>
</html>
Nikit Barochiya
la source
4

Vous pouvez utiliser la méthode ajaxSubmit comme suit :) lorsque vous sélectionnez un fichier qui doit être téléchargé sur le serveur, le formulaire doit être soumis au serveur :)

$(document).ready(function () {
    var options = {
    target: '#output',   // target element(s) to be updated with server response
    timeout: 30000,
    error: function (jqXHR, textStatus) {
            $('#output').html('have any error');
            return false;
        }
    },
    success: afterSuccess,  // post-submit callback
    resetForm: true
            // reset the form after successful submit
};

$('#idOfInputFile').on('change', function () {
    $('#idOfForm').ajaxSubmit(options);
    // always return false to prevent standard browser submit and page navigation
    return false;
});
});
Quy Le
la source
2
Je pense que vous parlez du plugin jquery form . C'est vraiment la meilleure option ici, à part le manque de détails dans votre réponse.
fotanus
@fotanus vous avez raison! ce script doit utiliser le plugin de formulaire jquery pour soumettre la méthode d'utilisation ajaxSubmit qui définit le plugin de formulaire jquery
Quy Le
4

pour télécharger un fichier qui est soumis par l'utilisateur dans le cadre d'un formulaire utilisant jquery, veuillez suivre le code ci-dessous:

var formData = new FormData();
formData.append("userfile", fileInputElement.files[0]);

Envoyez ensuite l'objet de données du formulaire au serveur.

Nous pouvons également ajouter un fichier ou un objet blob directement à l'objet FormData.

data.append("myfile", myBlob, "filename.txt");
VISHNU Radhakrishnan
la source
3

Si vous souhaitez télécharger un fichier à l'aide d'AJAX, voici le code que vous pouvez utiliser pour le téléchargement de fichiers.

$(document).ready(function() {
    var options = { 
                beforeSubmit:  showRequest,
        success:       showResponse,
        dataType: 'json' 
        }; 
    $('body').delegate('#image','change', function(){
        $('#upload').ajaxForm(options).submit();        
    }); 
});     
function showRequest(formData, jqForm, options) { 
    $("#validation-errors").hide().empty();
    $("#output").css('display','none');
    return true; 
} 
function showResponse(response, statusText, xhr, $form)  { 
    if(response.success == false)
    {
        var arr = response.errors;
        $.each(arr, function(index, value)
        {
            if (value.length != 0)
            {
                $("#validation-errors").append('<div class="alert alert-error"><strong>'+ value +'</strong><div>');
            }
        });
        $("#validation-errors").show();
    } else {
         $("#output").html("<img src='"+response.file+"' />");
         $("#output").css('display','block');
    }
}

Voici le HTML pour télécharger le fichier

<form class="form-horizontal" id="upload" enctype="multipart/form-data" method="post" action="upload/image'" autocomplete="off">
    <input type="file" name="image" id="image" /> 
</form>
Nikunj K.
la source
3

Pour obtenir toutes vos entrées de formulaire, y compris le type = "fichier", vous devez utiliser l' objet FormData . vous pourrez voir le contenu de formData dans le débogueur -> réseau -> En-têtes après avoir soumis le formulaire.

var url = "YOUR_URL";

var form = $('#YOUR_FORM_ID')[0];
var formData = new FormData(form);


$.ajax(url, {
    method: 'post',
    processData: false,
    contentType: false,
    data: formData
}).done(function(data){
    if (data.success){ 
        alert("Files uploaded");
    } else {
        alert("Error while uploading the files");
    }
}).fail(function(data){
    console.log(data);
    alert("Error while uploading the files");
});
David
la source
2
var dataform = new FormData($("#myform")[0]);
//console.log(dataform);
$.ajax({
    url: 'url',
    type: 'POST',
    data: dataform,
    async: false,
    success: function(res) {
        response data;
    },
    cache: false,
    contentType: false,
    processData: false
});
Jayesh Paunikar
la source
5
vous pouvez améliorer votre réponse en ajoutant quelques détails
SR
1

Voici une idée à laquelle je pensais:

Have an iframe on page and have a referencer.

Avoir un formulaire dans lequel vous déplacez l'élément INPUT: File vers.

Form:  A processing page AND a target of the FRAME.

Le résultat sera publié dans le cadre, puis vous pouvez simplement envoyer les données extraites d'un niveau à la balise d'image que vous souhaitez avec quelque chose comme:

data:image/png;base64,asdfasdfasdfasdfa

et la page se charge.

Je crois que cela fonctionne pour moi, et selon vous, vous pourrez peut-être faire quelque chose comme:

.aftersubmit(function(){
    stopPropigation()// or some other code which would prevent a refresh.
});
Fallenreaper
la source
Je ne vois pas comment cela améliore une autre réponse donnée auparavant. C'est aussi la propagation et non la propagation! ;)
JDuarteDJ