web-dev-qa-db-fra.com

Comment faire un téléchargement de fichiers asynchrone (AJAX) en utilisant iframe?

J'essaie de faire un téléchargement de fichier ajax. J'ai lu qu'il n'est pas possible de le faire sans utiliser iframe.
J'ai écrit :

<iframe id="uploadTrg" name="uploadTrg" height="0" width="0" frameborder="0" scrolling="yes"></iframe>
<form id="myForm" action="file-component" method="post" enctype="multipart/form-data"  target="uploadTrg">
File: <input type="file" name="file">
<input type="submit" value="Submit" id="submitBtn"/>
</form>

et en utilisant le plugin jquery form:

$('#myForm').ajaxForm({
    dataType:  'json',
    success:   function(data){
        alert(data.toSource());
    }
});

Le résultat:

le fichier est téléchargé avec succès et je peux voir le fichier téléchargé, mais une boîte de dialogue apparaît:

alt text

puisque je renvoie un résultat json pour afficher le nom du fichier + la taille etc.

Ma question: Comment puis-je utiliser l'iFrame pour pouvoir faire un "téléchargement de fichier ajax".

Remarque:

  1. Je ne préfère pas utiliser de plugin spécial pour télécharger le fichier, s'il existe des solutions plus appropriées/plus faciles.
  2. J'utilise jsp/servlets comme langue côté serveur .. mais je pense que la langue que j'utilise n'a pas de sens.

Merci

50
Abdullah

Je vais répondre à ma question, je pense avoir trouvé la solution. Voici les étapes que j'ai suivies pour atteindre l'objectif:

  1. Faites l'attribut "cible" du formulaire pointez sur "iframe".
  2. Utilisez une demande HTML normale (pas une demande asynchrone/Ajax) pour soumettre le formulaire.
  3. Parce que le cadre cible est iframe, la page entière ne sera pas actualisée - juste l'iframe.
  4. Une fois que iframe onload se produit (capturez cet événement en utilisant Javascript), faites ce que vous voulez, par exemple Vous pouvez renvoyer une demande pour répertorier les informations récentes sur les fichiers téléchargés.

Le code final ressemble à ceci:

    <!-- Attach a file -->

    <iframe id="uploadTrg" name="uploadTrg" height="0" width="0" frameborder="0" scrolling="yes"></iframe>

    <form id="myForm" action="http://example.com/file-upload-service" method="post" enctype="multipart/form-data"  target="uploadTrg">

        File: <input type="file" name="file">
        <input type="submit" value="Submit" id="submitBtn"/>

    </form>

    <div id="ajaxResultTest"></div>

javascript:

$("iframe").load(function(){
    // ok , now you know that the file is uploaded , you can do what you want , for example tell the user that the file is uploaded 
    alert("The file is uploaded");

    // or you can has your own technique to display the uploaded file name + id ? 
    $.post('http://example.com/file-upload-service?do=getLastFile',null,function(attachment){

       // add the last uploaded file , so the user can see the uploaded files
       $("#ajaxResultTest").append("<h4>" + attachment.name + ":" + attachment.id "</h4>");

    },'json');
});
95
Abdullah

Cet exemple tiré de BugKiller. exemple de travail complet qui vous permet de télécharger un logo et de le voir immédiatement dans la page html, après quoi la valeur de téléchargement est effacée:

html:

<form id="uploadForm" method="post" enctype="multipart/form-data"  target="uploadTrg">
  <div id="fileUploadWrapper"><input type="file" name="file" id="fileUpload"></div>
  <input type="submit" value="Upload" id="submitBtn"/>
</form>
<iframe id="uploadTrg" name="uploadTrg" height="0" width="0" frameborder="0" scrolling="no" style="display:none"></iframe>
<img id="imgLogo" style="border-width:0px;" />

javascript:

$(document).ready(function () {
  var companynumber = '12345'; //get this from the database
  var logoUploadUrl = 'UploadHandler.aspx?logoupload=true&companynumber=' + companynumber ;
  $("#uploadForm").attr("action", logoUploadUrl);

  $("#uploadTrg").load(function () {
    //upload complete

    //only way to reset contents of file upload control is to recreate it
    $("#fileUploadWrapper").html('<input type="file" name="file" id="fileUpload">');

    //reload the logo url, add ticks on the end so browser reloads it
    var ticks = ((new Date().getTime() * 10000) + 621355968000000000);
    var logoUrl = 'images/clients/' + companynumber + '/client.gif?' + ticks;
    $("#imgLogo").attr('src', logoUrl);
  });
});

télécharger le code du gestionnaire derrière (C #):

namespace MyWebApp {
    public partial class UploadHandler : System.Web.UI.Page {

        protected void Page_Load(object sender, EventArgs e) {
          if (Request.Params["logoupload"] != null) {
            string companynumber = Request.Params["companynumber"];
            string savePath = Server.MapPath("\\images") + "\\clients\\" + companynumber + "\\client.gif";
            if (File.Exists(savePath))
                File.Delete(savePath);
            //save the file to the server 
            Request.Files[0].SaveAs(savePath);

            Response.Write("OK");
            Response.Flush();
            Response.End();
          }
       }
}
4
JJ_Coder4Hire