30 votes

jquery file upload - IE done callback data.result issue

Je suis à l'aide d' jQuery le fichier de téléchargement du plugin.

Je n'utilise pas l' UI seulement de base.

Quand je fais ce qui suit, je vais avoir un problème en IE:

$('input#fileupload').fileupload({
    url: '/upload',
    done: function (e, data) {
    if(data.result != null && $.trim(data.result) != '')
        $('a#attachment').html(data.result);
    }
    //......................

sur IE le data.result est Object (IE9 au moins, pas sûr que les autres...)

Sur Chrome/Firefox est juste la réponse Text (simple texte brut à partir du serveur).

Des idées?

50voto

Justin Points 979

Je viens de tomber sur le même problème, et je pense que c'est dû au fait que XHR les uploads de fichier ne sont pas pris en charge dans IE (voire 9). Voici ce que je crois qui se passe, et ma solution:

Depuis Safari 5+, Firefox 4+, Chrome et soutien XHR téléchargement de fichiers, la fileupload plugin peut transférer les fichiers vraiment de manière asynchrone, ce qui permet un pur texte de la réponse du serveur. Ce texte pur réponse est disponible via data.result dans la done gestionnaire d'événements, et peut être utilisé facilement.

Dans IE, cependant, le transfert de fichiers se fait par une régénération complète de la page dans un iframe masqué, provoquant data.result dans la done gestionnaire à plein document de l'objet, avec le texte de la réponse enveloppé profondément à l'intérieur, <html><body><iframe><pre> tags.

Non seulement cela fait-il une douleur à obtenir les données dans IE, il fait le chemin, vous obtenez les données entre les différents navigateurs.

Ma solution:

J'ai mis l' forceIframeTransport option à true, ce qui permet à tous les navigateurs de transférer des fichiers avec un iframe masqué, comme IE. C'est dommage de passer à côté de XHR les uploads de fichier, mais cela donne au moins le même genre de réponse que dans tous les navigateurs. Alors, dans mon done gestionnaire, j'ai extrait le résultat de l' document objet comme ceci:

var result = $( 'pre', data.result ).text();

Dans votre cas, je pense que le code devrait ressembler à quelque chose comme ceci:

$('input#fileupload').fileupload({
    forceIframeTransport: true,
    url: '/upload',
    done: function ( e, data ) {
     var result = $( 'pre', data.result ).text();
     if( result != null && $.trim( result ) != '' )
        $( 'a#attachment' ).html( result );
    }
...

Également important à noter ici est que le Type de Contenu de la réponse de mon serveur est 'text/plain". Comme vous l'avez remarqué, c'est à dire, parfois, invite l'utilisateur à enregistrer ou d'ouvrir une réponse json.

Voici quelques liens qui s'avère utile lors de la résolution du problème: https://github.com/blueimp/jQuery-File-Upload/wiki/Browser-support (voir "XMLHttpRequest" de la section en bas) https://github.com/blueimp/jQuery-File-Upload/wiki/Options (voir "forceIframeTransport' environ 1/3 de la manière vers le bas)

Nous espérons que cette aide!

13voto

Unknown Points 111

J'ai eu des problèmes similaires à ceux mentionnés ci-dessus et j'ai constaté que le changement du type de réponse de application/json à text/plain résolu ces problèmes.

5voto

user2114134 Points 21

En fait, c'est à cela que sert jquery.iframe-transport.js (la version de base inclut également ce plugin comme référence supplémentaire). Ce dont vous avez besoin est de définir la propriété dataType sur json et le plugin jquery.iframe-transport analysera automatiquement le résultat iframe , afin que vous puissiez avoir la même logique dans votre gestionnaire terminé.

 $('#fileupload').fileupload({
...
    dataType: 'json'
...
});
 

4voto

Joey Points 326

J'ai rencontré ce même problème. IE 9 ne déclencherait pas le done de rappel, mais déclencherait le always rappel. La partie délicate consistait à extraire l'objet de réponse JSON des arguments. (Malgré ce que la documentation prétendait, je n'ai pas trouvé que je devais inclure jquery.iframe-transport.js.)

Mon implémentation du rappel always ressemblait à ceci:

 always: function(e, data) {
  var result;
  if (data.textStatus == 'parsererror') {  // IE9 fails on upload's JSON response
    result = JSON.parse(data.jqXHR.responseText);
  } else if (data.textStatus == 'success') {
    result = data.result;
  }

  if (result) {
    // ...perform custom handling...
  }
}
 

1voto

Pierre Henry Points 1940

Les réponses données ici ont été très utiles pour comprendre et résoudre le problème. J'ai fini avec une satisfaisante si hacky solution, qui permet à des navigateurs modernes à charger à l'aide de XmlHttpRequest, et IE9 utiliser iframe (n'a pas fait de test avec IE7/8) :

  • Utiliser jquery.iframe-transport.js, il prendra soin de l'extraction de la réponse de l'iframe. Simplement l'inclure dans la page, l' fileupload plugin va l'utiliser.
  • Sur le serveur d'action utilisé pour télécharger des fichiers, de retour d'un résultat JSON, mais avec content-type ensemble de "text/plain", afin d'éviter IE demander à l'utilisateur d'ouvrir le fichier
  • Dans le fait de rappel, manuellement evalutate le texte JSON
  • Enfin, utiliser le résultat évaluée objet comme avant

Voici le code JS :

//file upload
var upload = $(fileUploadElmtId).fileupload({

    dataType: 'text',  //if we use JSON IE9 will ask the user to open the file... see the FileUploadController class
    url: uploadUrl,
    autoUpload: true,

    done: function (e, data) {


        //parse the JSON string that was received from the server - since it was received as text/plain it is not automatically evaluated
        var result = $.parseJSON(data.result);

        $.each(result.files, function (index, file) {
            //do something with the result - in my case it is an array of uploaded files...
        }
    }
}

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