2013-05-28 17 views
13

Ho il seguente codice per scaricare un file .csv:utilizzando jQuery e iFrame per scaricare un programma

 $.ajax({ 
      url: urlString, 
      contentType: "application/json; charset=utf-8", 
      dataType: "json", 
      cache: false, 
      success: function (data) { 
       if (data) { 
        var iframe = $("<iframe/>").attr({ 
         src: data, 
         style: "visibility:hidden;display:none" 
        }).appendTo(buttonToDownloadFile); 
       } else { 
        alert('Something went wrong'); 
       } 
      } 
     }); 

L'urlString punta a un servizio RESTful che genera il file .csv e restituisce il percorso del file che è assegnato all'attributo src per l'iFrame. Funziona con qualsiasi file .csv ma ​​ho problemi con i file .xml. Quando uso lo stesso codice ma cambio contentType in "text/xml" e lo uso per scaricare file .xml, questo non funziona.

Posso usare lo stesso approccio qui per i file .xml?

UPDATE:

Grazie a Ben per avermi indirizzato verso la giusta direzione. A quanto pare non ho bisogno della chiamata ajax. Invece, posso semplicemente usare l'iFrame e il suo attributo url per chiamare il servizio web, che genererà il contenuto, aggiungere l'intestazione (Content-Disposition) e restituire lo stream.

risposta

11

Suppongo che il problema sia che la maggior parte dei browser proverà a eseguire il rendering XML nel browser stesso, mentre tendono a non avere alcun gestore per CSV, pertanto verranno automaticamente impostati per richiedere all'utente di scaricare il file. Prova a modificare le intestazioni del file XML per forzare il download. Qualcosa di simile (ad esempio PHP):

header("Content-Type: application/force-download"); 
header("Content-Type: application/octet-stream"); 
header("Content-Type: application/download"); 
header('Content-Disposition: attachment; filename="some filename"'); 

che dovrebbe dirvi maggior parte dei browser non tentare di aprire il file, ma invece di avere l'utente a scaricare il file e lasciare che il sistema operativo determinare che cosa fare con esso.

Se non si ha il potere di controllare le intestazioni nel file XML stesso, è possibile provare una soluzione utilizzando uno script sul lato server. Utilizzare JS per passare l'URL a uno script lato server:

//build the new URL 
var my_url = 'http://mysite.com/load_file_script?url='+escape(path_to_file); 
//load it into a hidden iframe 
var iframe = $("<iframe/>").attr({ 
         src: my_url, 
         style: "visibility:hidden;display:none" 
        }).appendTo(buttonToDownloadFile); 

e sul lato server (il vostro http://mysite.com/load_file_script sceneggiatura) si utilizza cURL/file_get_contents/wgets/[qualche altro meccanismo di recupero file remoti] per afferrare il contenuto del file remoto, aggiungere le intestazioni Content-Disposition: attachment e print il codice del file originale.

+0

Temo non capisco il lavoro -avresti suggerito. Il mio server è .NET (WCF). Stai dicendo che dovrei aggiungere le intestazioni dal lato server? – notlkk

+0

Sì. Se non controlli l'API RESTful, allora non è possibile impostare le intestazioni usando solo HTML/JS. Quindi, quello che fai è creare uno script sul tuo server .NET che possa ricevere l'URL remoto come argomento, andare a prendere il file remoto, re-impacchettarlo con nuove intestazioni e poi servirlo come allegato. –

+0

Vedo. Ho bisogno di tutte e 4 le intestazioni come hai sottolineato? E quale tipo di contenuto dovrei usare nel mio javascript? – notlkk

16

Si può anche offrire come download da un elemento di ancoraggio virtuale, anche se i dati sono sul lato client:

/* 
* Create an anchor to some inline data... 
*/ 

var url = 'data:application/octet-stream,Testing%20one%20two%20three'; 
var anchor = document.createElement('a'); 
    anchor.setAttribute('href', url); 
    anchor.setAttribute('download', 'myNote.txt'); 

/* 
* Click the anchor 
*/ 

// Chrome can do anchor.click(), but let's do something that Firefox can handle too 

// Create event 
var ev = document.createEvent("MouseEvents"); 
    ev.initMouseEvent("click", true, false, self, 0, 0, 0, 0, 0, false, false, false, false, 0, null); 

// Fire event 
anchor.dispatchEvent(ev); 

http://jsfiddle.net/D572L/

+2

Brillante. Questo mi ha semplicemente aiutato con un dilemma (l'output di un PDF generato utilizzando $ .ajax, in modo che è possibile visualizzare un caricatore facendo clic sul collegamento per il download e quindi nasconderlo nuovamente una volta che il file viene offerto al browser.) Grazie !! –

+1

Grazie! Funziona su iOS in opposto agli iframe nascosti – Lucas

+0

Impressionante! Grazie. –

Problemi correlati