Ho una webapp a pagina singola basata su jquery. Comunica con un servizio Web RESTful tramite chiamate AJAX.
Sto cercando di realizzare quanto segue:
- Invia un POST che contenga dati JSON a un URL REST.
- Se la richiesta specifica una risposta JSON, viene restituito JSON.
- Se la richiesta specifica una risposta PDF / XLS / etc, viene restituito un file binario scaricabile.
Ora lavoro 1 e 2 e l'app client jquery visualizza i dati restituiti nella pagina Web creando elementi DOM basati sui dati JSON. Ho anche # 3 funzionante dal punto di vista del servizio web, il che significa che creerà e restituirà un file binario se dati i parametri JSON corretti. Ma non sono sicuro del modo migliore per gestire il n. 3 nel codice javascript del client.
È possibile recuperare un file scaricabile da una chiamata Ajax come questa? Come posso scaricare e salvare il file dal browser?
$.ajax({
type: "POST",
url: "/services/test",
contentType: "application/json",
data: JSON.stringify({category: 42, sort: 3, type: "pdf"}),
dataType: "json",
success: function(json, status){
if (status != "success") {
log("Error loading data");
return;
}
log("Data loaded!");
},
error: function(result, status, err) {
log("Error loading data");
return;
}
});
Il server risponde con le seguenti intestazioni:
Content-Disposition:attachment; filename=export-1282022272283.pdf
Content-Length:5120
Content-Type:application/pdf
Server:Jetty(6.1.11)
Un'altra idea è quella di generare il PDF e archiviarlo sul server e restituire JSON che include un URL al file. Quindi, invia un'altra chiamata nel gestore del successo di Ajax per fare qualcosa di simile al seguente:
success: function(json,status) {
window.location.href = json.url;
}
Ma ciò significa che avrei bisogno di effettuare più di una chiamata al server e il mio server avrebbe bisogno di creare file scaricabili, archiviarli da qualche parte, quindi ripulire periodicamente quell'area di archiviazione.
Ci deve essere un modo più semplice per raggiungere questo obiettivo. Idee?
EDIT: Dopo aver esaminato i documenti per $ .ajax, vedo che il tipo di dati di risposta può essere solo uno dei xml, html, script, json, jsonp, text
, quindi suppongo che non ci sia modo di scaricare direttamente un file usando una richiesta ajax, a meno che io non incorpori il file binario nell'uso Schema URI dei dati come suggerito nella risposta @VinayC (che non è qualcosa che voglio fare).
Quindi immagino che le mie opzioni siano:
Non usare Ajax e invece inviare un post di modulo e incorporare i miei dati JSON nei valori del modulo. Probabilmente avrebbe bisogno di pasticciare con iframe nascosti e simili.
Non usare Ajax e invece convertire i miei dati JSON in una stringa di query per creare una richiesta GET standard e impostare window.location.href su questo URL. Potrebbe essere necessario utilizzare event.preventDefault () nel mio gestore di clic per impedire che il browser cambi dall'URL dell'applicazione.
Usa la mia altra idea sopra, ma migliorata con i suggerimenti della risposta @naikus. Invia la richiesta AJAX con alcuni parametri che consentono al servizio web di sapere che viene chiamato tramite una chiamata Ajax. Se il servizio Web viene chiamato da una chiamata Ajax, è sufficiente restituire JSON con un URL alla risorsa generata. Se la risorsa viene chiamata direttamente, restituisce il file binario effettivo.
Più ci penso, più mi piace l'ultima opzione. In questo modo posso ottenere informazioni sulla richiesta (tempo di generazione, dimensione del file, messaggi di errore, ecc.) E posso agire su tali informazioni prima di iniziare il download. Il rovescio della medaglia è la gestione dei file extra sul server.
Altri modi per raggiungere questo obiettivo? Qualche pro / contro di questi metodi di cui dovrei essere a conoscenza?
url = 'http://localhost/file.php?file='+ $('input').val(); window.open(url);
Il modo semplice per ottenere gli stessi risultati. Inserisci l'intestazione nel file php. Non è necessario inviare ajax o ricevere richieste