Mam klasę akcji, która generuje plik PDF. contentType
Jest ustawiony prawidłowo.
public class MyAction extends ActionSupport
{
public String execute() {
...
...
File report = signedPdfExporter.generateReport(xyzData, props);
inputStream = new FileInputStream(report);
contentDisposition = "attachment=\"" + report.getName() + "\"";
contentType = "application/pdf";
return SUCCESS;
}
}
Wołam to action
przez połączenie Ajax. Nie znam sposobu dostarczenia tego strumienia do przeglądarki. Próbowałem kilku rzeczy, ale nic nie działało.
$.ajax({
type: "POST",
url: url,
data: wireIdList,
cache: false,
success: function(response)
{
alert('got response');
window.open(response);
},
error: function (XMLHttpRequest, textStatus, errorThrown)
{
alert('Error occurred while opening fax template'
+ getAjaxErrorString(textStatus, errorThrown));
}
});
Powyższe podaje błąd:
Twoja przeglądarka wysłała żądanie, którego ten serwer nie mógł zrozumieć.
źródło
content-disposition
jest ustawiony naattachment
, otrzymasz po prostuSave as
dialog. Strona nadrzędna pozostanie niezmieniona. Po prostu<a href="pdfservlet/filename.pdf">pdf</a>
lub a<form action="pdfservlet/filename.pdf"><input type="submit"></form>
jest więcej niż wystarczające.POST
dane.Oto jak to działa
Zaktualizowana odpowiedź za pomocą download.js
źródło
Nie wydaje mi się, żeby którakolwiek z wcześniejszych odpowiedzi wskazywała na problem z oryginalnym plakatem. Wszyscy zakładają żądanie GET, podczas gdy plakat próbował POST dane i pobrać w odpowiedzi.
W trakcie poszukiwania lepszej odpowiedzi znaleźliśmy tę wtyczkę jQuery do pobierania plików w stylu Ajax .
W swoim „sercu” tworzy „tymczasowy” formularz HTML zawierający podane dane jako pola wejściowe. Ten formularz jest dołączany do dokumentu i publikowany pod żądanym adresem URL. Zaraz po tym formularz jest ponownie usuwany:
Odpowiedź Update Mayur wygląda całkiem obiecująco i bardzo prosto w porównaniu z wtyczką jQuery, o której mówiłem.
źródło
W ten sposób rozwiązuję ten problem.
Odpowiedź Jonathana Amenda w tym poście bardzo mi pomogła.
Poniższy przykład jest uproszczony.
Aby uzyskać więcej informacji, powyższy kod źródłowy może pobrać plik przy użyciu żądania JQuery Ajax (GET, POST, PUT itp . ) . Pomaga również w przesyłaniu parametrów jako JSON i zmianie typu zawartości na application / json (moje domyślne) .
Html źródło:
Prosty formularz z dwoma tekstami wejściowymi, jednym przyciskiem wyboru i przyciskiem.
Strona javascript źródło:
Proste wydarzenie po kliknięciu przycisku. Tworzy obiekt AjaxDownloadFile. Źródło klasy AjaxDownloadFile znajduje się poniżej.
Klasa AjaxDownloadFile źródło:
Stworzyłem tę klasę, aby dodać ją do mojej biblioteki JS. Jest wielokrotnego użytku. Mam nadzieję, że to pomoże.
źródło
Blob
obiekt jest obsługiwany w IE10 +.responseType
xhr naarraybuffer
lubblob
aby to działało. (W przeciwnym razie działa świetnie.)U mnie zadziałał następujący kod, który pobiera funkcja serwera
File(memoryStream.GetBuffer(), "application/pdf", "fileName.pdf");:
źródło
Możesz użyć tej wtyczki, która tworzy formularz i przesyła go, a następnie usuwa ze strony.
To zadziałało dla mnie. Znalazłem tę wtyczkę tutaj
źródło
Poniższy kod zadziałał dla mnie
źródło
Aby rozwiązać problem z pustym plikiem PDF w żądaniu pocztowym, aby uzyskać dane strumieniowe, takie jak PDF, musimy dodać typ odpowiedzi jako „bufor tablicy” lub „blob” w żądaniu
źródło
Jeśli chodzi o odpowiedź udzieloną przez Mayura Padshalę, jest to poprawna logika pobierania pliku PDF przez ajax, ale jak inni podają w komentarzach, to rozwiązanie faktycznie pobiera pusty plik PDF.
Przyczyna tego jest wyjaśniona w zaakceptowanej odpowiedzi na to pytanie : jQuery ma pewne problemy z ładowaniem danych binarnych przy użyciu żądań AJAX, ponieważ nie implementuje jeszcze niektórych funkcji HTML5 XHR v2, zobacz tę prośbę o ulepszenie i tę dyskusję .
Więc użycie
HTMLHTTPRequest
kodu powinno wyglądać tak:źródło
utwórz ukrytą ramkę iframe, a następnie w swoim kodzie Ajax powyżej:
URL:
document.getElementById('myiframeid').src = your_server_side_url
,i usuń
window.open(response);
źródło
Ten fragment kodu jest przeznaczony dla użytkowników angular js, którzy napotkają ten sam problem. Należy zauważyć, że plik odpowiedzi jest pobierany przy użyciu zaprogramowanego zdarzenia kliknięcia. W tym przypadku nagłówki zostały wysłane przez serwer zawierający nazwę pliku i zawartość / typ.
źródło
Czy musisz to zrobić z Ajaxem? Czy nie mogłaby być możliwość załadowania go w ramce iframe?
źródło
Mam nadzieję, że pozwoli to zaoszczędzić kilka godzin i uniknąć bólu głowy. Zajęło mi trochę czasu, zanim to rozgryzłem, ale wykonanie zwykłego żądania $ .ajax () zrujnowało mój plik PDF, podczas gdy żądanie go przez pasek adresu działało idealnie. Rozwiązanie było następujące:
Dołącz download.js: http://danml.com/download.html
Następnie użyj XMLHttpRequest zamiast żądania $ .ajax ().
źródło
źródło
Jeśli musisz pracować ze strumieniem plików (więc nie ma fizycznie zapisanego pliku PDF), tak jak my, i chcesz pobrać plik PDF bez ponownego ładowania strony, działa dla nas następująca funkcja:
HTML
Javascript
Ze względu na to, że target = "pdf-download-output" , odpowiedź jest zapisywana w ramce iframe i dlatego nie jest wykonywane ponowne ładowanie strony, ale strumień odpowiedzi pdf jest wysyłany do przeglądarki jako plik do pobrania.
źródło