839 votes

jQuery Ajax File Upload

Puis-je utiliser le code jQuery suivant pour télécharger un fichier en utilisant la méthode POST d'une requête ajax ?

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

Si c'est possible, est-ce que je dois remplir data partie ? Est-ce que c'est la bonne façon de faire ? Je ne fais que POSTER le fichier du côté du serveur.

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

0 votes

Ajax ne prend pas en charge les téléchargements de fichiers, vous devez utiliser iframe à la place.

1 votes

2 votes

639voto

Adeel Points 9888

Le téléchargement de fichiers est no possible grâce à AJAX.
Vous pouvez télécharger un fichier, sans rafraîchir la page en utilisant IFrame .
Vous pouvez vérifier plus de détails aquí .


UPDATE

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

FormData La prise en charge commence à partir des versions suivantes des navigateurs de bureau.

  • IE 10+ (EN ANGLAIS)
  • Firefox 4.0+.
  • Chrome 7+ (en anglais)
  • Safari 5+
  • Opera 12+.

Pour plus de détails, voir Lien MDN .

44 votes

Voici une liste des navigateurs spécifiques qui ne sont pas pris en charge : caniuse.com/#search=FormData Je ne l'ai pas testé mais voici un polyfill pour FormData. gist.github.com/3120320

167 votes

Plus précisément, IE < 10 ne le fait pas, pour ceux qui sont trop paresseux pour lire le lien.

0 votes

2 pensées : 1ère : c'est ce qui rend le développement web si hilarant et sauvage. 2ème : Vicary - il aborde la partie "jquery" de la question en la déclarant simplement comme irréelle au moment où elle a été postée - à ces fins, 100% précis et utile. ADEEL - +1 grande réponse, ne serait-ce que parce que la rétrocompatibilité est primordiale.

373voto

Ziinloader Points 1287

Iframes n'est plus nécessaire pour télécharger des fichiers par ajax. Je l'ai récemment fait moi-même. Regardez ces pages :

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

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

J'ai mis à jour la réponse et l'ai nettoyée. Utilisez la fonction getSize pour vérifier la taille ou 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;
}

4 votes

Vous pouvez plus ou moins copier le code directement et l'utiliser. Il suffit de changer certains noms d'identifiants et de classes. Toute personnalisation est à votre charge.

4 votes

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.

8 votes

Je ne pense pas que nous puissions l'utiliser tel quel @Ziinloader. Vous utilisez une méthode locale qui n'est pas incluse : writer(catchFile) . Qu'est-ce que writer() ?

248voto

pedrozopayares Points 23

Il est possible d'envoyer et de télécharger des fichiers par Ajax. J'utilise jQuery $.ajax pour charger mes fichiers. J'ai essayé d'utiliser l'objet XHR mais je n'ai pas pu obtenir de résultats du 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, et ensuite joindre le fichier d'entrée.

Voici de plus amples informations : - Comment télécharger un fichier en utilisant jQuery.ajax et FormData - Téléchargement de fichiers via jQuery, l'objet FormData est fourni et aucun nom de fichier, requête 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
            ));
}

2 votes

Quelle bibliothèque jquery dois-je référencer pour exécuter ce code ?

0 votes

La réponse a été rédigée en 2014. La version de JQuery était la 1.10. Je n'ai pas essayé avec des versions plus récentes.

6 votes

formData.append('file', $('#file')[0].files[0]); renvoie à undefined y console.log(formData) n'a rien sauf _proto_

74voto

lee8oi Points 113

J'arrive un peu tard, mais je cherchais une solution pour télécharger des images par ajax et la réponse que je cherchais était un peu éparpillée dans ce post. La solution que j'ai retenue fait appel à l'objet FormData. J'ai assemblé une forme basique du code que j'ai mis ensemble. Vous pouvez voir qu'il démontre comment ajouter un champ personnalisé au formulaire avec fd.append() ainsi que comment gérer les données de réponse lorsque la requête ajax est terminée.

Téléchargez le 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>

Si vous travaillez avec php, voici une façon de gérer le téléchargement qui inclut l'utilisation des deux champs personnalisés présentés dans le html ci-dessus.

Télécharger.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";
}
?>

0 votes

Je reçois Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https, pourquoi est-ce ainsi monsieur je copier coller votre code tel qu'il est

2 votes

@HogRider - si vous cherchez votre message d'erreur sur Google, voici le premier résultat : stackoverflow.com/questions/10752055/ Accédez-vous à vos pages web localement par file:// plutôt que d'utiliser un serveur web ? Par ailleurs, ce n'est pas une bonne pratique que de copier-coller aveuglément du code sans le comprendre. Je vous recommande de parcourir le code ligne par ligne pour comprendre ce qui se passe avant de l'utiliser.

0 votes

J'ai parcouru le document ligne par ligne et je n'ai pas vraiment compris grand-chose. J'ai donc posé la question pour que quelqu'un puisse clarifier mes doutes. J'utilise local by way xampp pour être exact. Puis-je poser une question que vous pourrez peut-être clarifier ?

35voto

koppor Points 2066

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

Pour plus de détails, voir : Réponse https://stackoverflow.com/a/4943774/873282 à la question jQuery Upload Progress et AJAX file upload .

24 votes

Malheureusement, IE < 10 ne supporte pas cela.

1 votes

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 tel message ressemble à une tentative de gagner des points.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X