Datei mit ajax() POST-Anfrage über Spring MVC herunterladen
Lesezeit: 6 Minuten
derlinuxer
Ich versuche eine Datei herunterzuladen. Die Aktion wird ausgelöst durch ajax() POST-Anfrage. Die Anfrage wird gesendet Daten im JSON-Format an den Controller. Die Steuerung generiert die Datei (Bytes) und sendet sie zurück.
Der Browser sollte eine Download-Box öffnen, aber es passiert nicht
Die Antwort wird im Abschnitt error: der Ajax-Funktion behandelt (aber der HTTP-Status ist OK)
Was mache ich also falsch oder wie mache ich das richtig?
Du stellst ein dataType: 'json' aber eine Art Lizenzdatei senden? Ich glaube auch nicht, dass Sie Ajax verwenden können, um eine Datei herunterzuladen.
– Musa
22. November ’12 um 19:50
Der Versuch, eine Datei herunterzuladen, die mit Ajax im lokalen Verzeichnis gespeichert werden soll, kann nicht durchgeführt werden und ist viel mehr Code, als einfach nur auf die Datei-URL selbst zu verweisen
– charlietfl
22. November ’12 um 20:05
stackoverflow.com/questions/3613526/… könnte gut helfen
– Robust
22. November ’12 um 21:18 Uhr
Habe eine funktionierende Lösung gefunden: Wie kommuniziert man richtig. Soll ich meine Frage selbst beantworten???
– derlinuxer
23. November ’12 um 12:48
@derlinuxer Könnten Sie bitte die gefundene funktionierende Lösung teilen? Ich habe genau das gleiche Problem…
– will824
24. Juli ’13 um 23:02
Senden Sie einfach eine URL der Datei als Antwort und “besuchen” Sie sie dann in Ihrem success Ruf zurück.
hmm, normalerweise möchte ich die Datei nicht im Dateisystem auf der Serverseite speichern und auch eine saubere Download-URL haben. Generieren Sie einfach im Speicher und senden Sie die Bytes zurück. Aber ich muss es wirklich mit zwei Controller-Methoden tun. Die erste Methode generiert die Datei (speichert auf dem Server FS) und gibt den Dateinamen im JSON-Format zurück. Und die zweite Methode sendet die Dateidaten. So kann ich verhindern, dass ein sauberer Download-Pfad vorhanden ist. Ich werde das überprüfen.
– derlinuxer
23. November ’12 um 8:57
window.open(data.fileUrl); funktioniert nicht in einer asynchronen Umgebung. window.location.href = data.fileUrl; funktioniert perfekt!
– lekant
10. Dezember ’15 um 7:40
derlinuxer
@will824 Wie Sie fragen, werde ich meine eigene Lösung posten.
Ich habe einen Workaround im Controller verwendet und die Datei vorübergehend im Dateisystem gespeichert (/tmp). Ich habe die Funktion in 2 Schritte aufgeteilt. Erstellen und herunterladen. Das ist nicht sehr schön, aber gut genug für mich.
Regler (erzeugt eine Datei, wird im Dateisystem des Servers gespeichert):
@RequestMapping(value = "/licenses/rest", method = RequestMethod.PUT)
@ResponseStatus(value=HttpStatus.OK)
@ResponseBody
public String createLicenseFile(@Valid @RequestBody License license) throws Exception {
// create encrypted license file and send the name back to view
String fileName = licenseEncodeDefaultService.createLicenseFile(license);
return fileName;
}
Regler (lädt eine Datei herunter):
@RequestMapping(value = "/licenses/downloadFile/{file}", method = RequestMethod.GET)
public void downloadLicenseFile(@PathVariable("file") String file, HttpServletResponse response) throws Exception {
// create full filename and get input stream
File licenseFile = new File ("/tmp/" + file);
InputStream is = new FileInputStream(licenseFile);
// set file as attached data and copy file data to response output stream
response.setHeader("Content-Disposition", "attachment; filename="" + file + ".license"");
FileCopyUtils.copy(is, response.getOutputStream());
// delete file on server file system
licenseFile.delete();
// close stream and return to view
response.flushBuffer();
}
Vielen Dank für Ihre Antwort. Ich stimme zu, dass dies einen 1-Schritt-einfachen Prozess macht, um zweimal zum Server zu gehen, aber Ihre Lösung ist mehr oder weniger ähnlich der, die ich implementieren wollte, trotzdem durfte ich nicht zweimal zum Server gehen, also musste ich einfach gehen mit dem 1-Schritt-Aufruf, indem Sie ein unsichtbares Formular mit einem iframe verwenden, und akzeptieren Sie das Risiko, dass der Benutzer bei einem Fehler nie weiß, was passiert ist.
– will824
13. August ’13 um 16:54
Benutzer4532418
Wenn Sie die Datei herunterladen möchten, ohne die URL zu ändern, können Sie anrufen form.submit()programmatisch anstatt AJAX zu verwenden.
JavaScript:
function downloadFileUsingForm(url) {
var form = document.createElement("form");
form.method = "post";
form.action = url;
document.body.appendChild(form);
form.submit();
document.body.removeChild(form);
}
downloadFileUsingForm("/YourController/DownloadFile");
Dies ist die beste Antwort, die ich für den Fall gefunden habe, an dem ich arbeite.
– Poly
12. Okt ’16 um 12:19
Als Anmerkung: die Frage bezog sich auf Spring MVC (daher Java), aber Ihr Controller-Beispiel ist in C# und .NETZ
– informatik01
13. November ’19 um 18:05
Beim Absenden eines Formulars wird kein JSON gesendet, das in den Fragen erforderlich war, daher ist diese Antwort falsch.
– Plamen
25. März ’21 um 19:52
Wie die Kommentare sagten, können Sie dies nicht mit einem Ajax-Aufruf tun, aber Sie können es mit einfachem Javascript tun.
function getLicenseFile() {
var downloadUrl = "${pageContext.request.contextPath}/licenses/rest/downloadLicenseFile";
// (optionally) provide the user with a message that the download is starting
window.location.href = downloadUrl;
}
Beachten Sie die Verwendung von ${pageContext.request.contextPath}, was vorgezogen wird <%=request.getContextPath()%>.
Ajax wird Ihnen nicht helfen, den Ansatz mit versteckten Formularen auszuprobieren
Du stellst ein
dataType: 'json'
aber eine Art Lizenzdatei senden? Ich glaube auch nicht, dass Sie Ajax verwenden können, um eine Datei herunterzuladen.– Musa
22. November ’12 um 19:50
Der Versuch, eine Datei herunterzuladen, die mit Ajax im lokalen Verzeichnis gespeichert werden soll, kann nicht durchgeführt werden und ist viel mehr Code, als einfach nur auf die Datei-URL selbst zu verweisen
– charlietfl
22. November ’12 um 20:05
stackoverflow.com/questions/3613526/… könnte gut helfen
– Robust
22. November ’12 um 21:18 Uhr
Habe eine funktionierende Lösung gefunden: Wie kommuniziert man richtig. Soll ich meine Frage selbst beantworten???
– derlinuxer
23. November ’12 um 12:48
@derlinuxer Könnten Sie bitte die gefundene funktionierende Lösung teilen? Ich habe genau das gleiche Problem…
– will824
24. Juli ’13 um 23:02