caricamento file jquery – IE ha fatto callback data.result problema

Sto usando il plugin per il caricamento di file jQuery .

Non uso la parte UI , solo quella di base.

Quando faccio quanto segue, sto riscontrando un problema in IE :

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

su IE il data.result è un Object (almeno IE9 , non sono sicuro degli altri …)

Su Chrome / Firefox c’è solo la risposta Text (semplice testo in chiaro dal server).

    Idee?

    Ho appena incontrato lo stesso problema, e penso che sia dovuto al fatto che i caricamenti di file XHR non sono supportati in IE (anche 9). Ecco cosa credo stia accadendo e la mia soluzione:

    Poiché Safari 5+, Firefox 4+ e Chrome supportano i caricamenti di file XHR, il plugin fileupload può trasferire i file in modo veramente asincrono, consentendo una risposta puramente testuale dal server. Questa risposta puramente testuale è disponibile tramite data.result nel gestore eventi done e può essere utilizzata facilmente.

    In IE, tuttavia, il trasferimento del file avviene tramite l’aggiornamento di una pagina completa in un iframe nascosto, facendo data.result che data.result nel gestore done sia un object document completo, con il testo della risposta racchiuso in profondità all’interno di tag.

    Ciò non solo rende difficile accedere ai dati in IE, ma rende anche i dati diversi tra i vari browser.

    La mia soluzione:

    Ho impostato l'opzione forceIframeTransport su true, che consente a tutti i browser di trasferire file con un iframe nascosto, ad esempio IE. È sfortunato perdere i caricamenti di file XHR, ma questo almeno ci dà lo stesso tipo di risposta in tutti i browser. Quindi, nel mio gestore di done , ho estratto il risultato dall'object del document modo:

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

    Nel tuo caso, penso che il codice sarebbe simile a questo:

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

    È importante notare che il tipo di contenuto della risposta del mio server è "text / plain". Come avrai notato, IE a volte richiede all'utente di salvare o aprire una risposta JSON.

    Ecco alcuni link utili per risolvere il problema: https://github.com/blueimp/jQuery-File-Upload/wiki/Browser-support (vedere la sezione "XMLHttpRequest" in fondo) https://github.com / blueimp / jQuery-File-Upload / wiki / Opzioni (vedi 'forceIframeTransport' circa 1/3 del modo in basso)

    Speriamo che questo aiuti!

    Ho avuto problemi simili a quelli menzionati sopra e ho scoperto che la modifica del tipo di risposta da application/json a text/plain risolto questi problemi.

    In realtà questo è ciò che jquery.iframe-transport.js (la versione base include anche questo plugin come riferimento aggiuntivo). Quello di cui hai bisogno è impostare la proprietà dataType su json e il plugin jquery.iframe-transport analizzerà automaticamente il risultato iframe , così puoi avere la stessa logica nel tuo gestore fatto.

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

    Mi sono imbattuto in questo stesso problema. IE 9 non triggersva la richiamata done , ma triggersva la richiamata always . La parte difficile era estrarre l’object di risposta JSON dagli argomenti. (Nonostante quanto affermato dalla documentazione, non ho trovato che dovessi includere jquery.iframe-transport.js.)

    La mia implementazione del callback always assomigliava a questo:

     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... } } 

    Le risposte qui sono state molto utili per capire e risolvere il problema. Ho finito con una soluzione hacky soddisfacente, che consente ai browser moderni di caricare utilizzando XmlHttpRequest e IE9 per utilizzare iframe (non testato con IE7 / 8):

    • Usa jquery.iframe-transport.js , si occuperà di estrarre la risposta dall’iframe. fileupload nella pagina, il plugin fileupload lo userà.
    • Sull’azione del server utilizzata per caricare i file, restituire un risultato JSON, ma con content-type impostato su "text/plain" , per evitare che IE richieda all’utente di aprire il file
    • Nel callback fatto, valutare manualmente il testo JSON
    • Infine, usa l’object risultato valutato come prima

    Ecco il codice 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... } } } 

    Grazie a @Justin per una grande spiegazione su questo. Eviterei di fare domande per l’elemento “pre” e invece di fare una soluzione semplice come commentato da @EnsignRicky

     done: function (e, data) { var result = data.result[0].body ? data.result[0].body.innerHTML : data.result } 

    Il mio problema, la ragione è: Cross-Domain.

    Vale a dire: in IE8 / 9, l’URL del tuo server dovrebbe appartenere allo stesso dominio del tuo file js. Per jquery.iframe-transport.js si basa su iframe, in cui non è ansible eseguire il dominio incrociato. Controlla hehe

    Non è necessario impostare forceIframeTransport su true, poiché jquery.file-upload.js giudicherà il browser stesso.

    Il tuo server dovrebbe restituire Content-Type: text / html, o magari text / plain, e js potrebbe usare dataType: ‘json’, nessun problema. Almeno, il mio è.

    Quando esegui il debug, puoi impostare breakpoint in jquery.iframe-transport.js a circa line85, il blocco try / catch. Se si può rompere lì, ciò significa che iframe è stato utilizzato e si potrebbe ottenere la risposta. A questo punto, potresti vedere il tuo jSON nel DOM (in iframe), ma se hai un dominio incrociato, avresti la risposta come non definita.

    Il mio codice Non speciale:

     $('.input-upload').fileupload({ url: url, dataType: 'json', autoUpload: false, acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i, maxFileSize: 999000, previewMaxWidth: 114, previewMaxHeight: 70, previewThumbnail: false, xhrFields: { withCredentials: true } }).on('fileuploadadd', function (e, data) { $.each(data.files, function (index, file) { data.submit().success(function (json, textStatus, jqXHR) { // on success }).error(function (jqXHR, textStatus, errorThrown) { // on error }); }); }).on('fileuploadprocessalways', function (e, data) { var _this = this; var file = data.files[data.index]; if (file.preview) { // 显示图片预览var preview = $(this).parent().siblings('.preview'); preview.append(file.preview).removeHide(); } }); 

    Credo che il problema possa essere nella risposta del server, puoi assicurarti che il server invii sempre l’intestazione corretta usando il seguente codice:

     header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); header("Last-Modified: " . gmdate("D, d MYH:i:s") . "GMT"); header("Cache-Control: no-cache, must-revalidate"); header("Pragma: no-cache"); header("Content-type: text/x-json"); echo json_encode($array); exit(0);