Ich habe eine jquery-basierte einseitige Webanwendung. Es kommuniziert mit einem RESTful-Webdienst über AJAX-Aufrufe.
Ich versuche Folgendes zu erreichen:
- Senden Sie einen POST, der JSON-Daten enthält, an eine REST-URL.
- Wenn die Anforderung eine JSON-Antwort angibt, wird JSON zurückgegeben.
- Wenn die Anforderung eine PDF / XLS / etc-Antwort angibt, wird eine herunterladbare Binärdatei zurückgegeben.
Ich habe 1 & 2 jetzt arbeiten, und die Client-Abfrage-App zeigt die zurückgegebenen Daten auf der Webseite an, indem sie DOM-Elemente basierend auf den JSON-Daten erstellt. Ich habe auch # 3 aus der Sicht des Webdienstes, was bedeutet, dass eine Binärdatei erstellt und zurückgegeben wird, wenn die richtigen JSON-Parameter angegeben werden. Ich bin mir jedoch nicht sicher, wie ich am besten mit # 3 im Client-Javascript-Code umgehen soll.
Ist es möglich, eine herunterladbare Datei von einem Ajax-Aufruf wie diesem zurückzubekommen? Wie kann ich den Browser dazu bringen, die Datei herunterzuladen und zu speichern?
$.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;
}
});
Der Server antwortet mit folgenden Headern:
Content-Disposition:attachment; filename=export-1282022272283.pdf
Content-Length:5120
Content-Type:application/pdf
Server:Jetty(6.1.11)
Eine andere Idee besteht darin, die PDF-Datei zu generieren, auf dem Server zu speichern und JSON zurückzugeben, das eine URL zur Datei enthält. Rufen Sie dann den Ajax Success Handler erneut auf, um Folgendes zu tun:
success: function(json,status) {
window.location.href = json.url;
}
Dies bedeutet jedoch, dass ich mehr als einen Anruf beim Server tätigen muss und mein Server herunterladbare Dateien erstellen, irgendwo speichern und dann diesen Speicherbereich regelmäßig bereinigen muss.
Es muss einen einfacheren Weg geben, dies zu erreichen. Ideen?
BEARBEITEN: Nachdem ich die Dokumente auf $ .ajax überprüft habe, sehe ich, dass der Antwortdatentyp nur einer von sein xml, html, script, json, jsonp, text
kann. Ich vermute, dass es keine Möglichkeit gibt, eine Datei mithilfe einer Ajax-Anforderung direkt herunterzuladen, es sei denn, ich binde die Binärdatei in using ein Daten-URI-Schema, wie in der @ VinayC-Antwort vorgeschlagen (was ich nicht tun möchte).
Ich denke also, meine Optionen sind:
Verwenden Sie nicht Ajax und senden Sie stattdessen einen Formularbeitrag und binden Sie meine JSON-Daten in die Formularwerte ein. Müsste wahrscheinlich mit versteckten Iframes und so weiter herumspielen.
Verwenden Sie nicht Ajax und konvertieren Sie stattdessen meine JSON-Daten in eine Abfragezeichenfolge, um eine Standard-GET-Anforderung zu erstellen und window.location.href auf diese URL zu setzen. Möglicherweise muss event.preventDefault () in meinem Klick-Handler verwendet werden, um zu verhindern, dass sich der Browser von der Anwendungs-URL ändert.
Verwenden Sie meine andere Idee oben, aber erweitert mit Vorschlägen aus der @ naikus-Antwort. Senden Sie eine AJAX-Anfrage mit einem Parameter, der den Webdienst darüber informiert, dass dies über einen Ajax-Aufruf aufgerufen wird. Wenn der Webdienst von einem Ajax-Aufruf aufgerufen wird, geben Sie JSON einfach mit einer URL an die generierte Ressource zurück. Wenn die Ressource direkt aufgerufen wird, geben Sie die eigentliche Binärdatei zurück.
Je mehr ich darüber nachdenke, desto mehr gefällt mir die letzte Option. Auf diese Weise kann ich Informationen über die Anforderung (Zeit zum Generieren, Dateigröße, Fehlermeldungen usw.) zurückerhalten und auf diese Informationen reagieren, bevor ich mit dem Download beginne. Der Nachteil ist die zusätzliche Dateiverwaltung auf dem Server.
Gibt es noch andere Möglichkeiten, dies zu erreichen? Gibt es Vor- und Nachteile dieser Methoden, die mir bekannt sein sollten?
url = 'http://localhost/file.php?file='+ $('input').val(); window.open(url);
Der einfache Weg, um die gleichen Ergebnisse zu erzielen. Setzen Sie den Header in PHP-Datei. Keine Notwendigkeit,