POST на сервер, получать PDF, доставлять пользователю w / jQuery

У меня есть ссылка, которую пользователь нажимает, чтобы получить PDF-файл. В jQuery я создаю ajax-вызов POST для сервера, чтобы получить PDF-файл. PDF подходит ко мне с правильными заголовками содержимого и т. Д., Которые обычно заставляют браузер открывать плагин Reader или позволяют пользователю сохранять PDF-файл.

Поскольку я получаю PDF с вызовом ajax, я не уверен, что делать с данными, которые я получаю в обратном вызове OnSuccess. Как я могу предоставить данные, которые я получаю в браузере, и позволить ему выполнять свою задачу по умолчанию с ответом PDF?

Вам совсем не нужен jQuery. Просто отправьте свой POST через форму, как правило, и на стороне сервера добавьте заголовок HTTP

 Content-Disposition: attachment; filename="whatever.pdf" 

Браузер выполнит свою задачу по умолчанию.

В качестве альтернативы, если вы хотите быть более внимательными к сообщениям о любых ошибках, которые могут возникнуть во время генерации PDF, вы можете это сделать. Отправьте свои параметры на свой сервер с помощью jQuery. На сервере сгенерируйте двоичный контент и кешируйте его где-нибудь в течение нескольких минут, ansible с помощью ключа, который вы помещаете в сеанс пользователя, и возвращаете ответ «Ajax» на вашу страницу (или если произошла ошибка, верните ответ «ошибка»). Если страница возвращает ответ успеха, она может немедленно сделать что-то вроде:

 window.location = "/get/my/pdf"; 

Затем сервер возвращает содержимое кэшированного PDF-файла. Не забудьте включить заголовок Content-Disposition, как указано выше.

Взгляните на – jQuery Plugin для запроса Ajax-подобных файлов

Весь plugin составляет около 30 строк кода (включая комментарии).

Вызов довольно похож на вызов jquery ajax.

 $.download('/export.php','filename=myPDF&format=pdf&content=' + pdfData ); 

Конечно, вы должны установить заголовки содержимого и Content-Disposition на стороне сервера, как и для любой такой загрузки.

В java я бы сделал что-то вроде этого

 response.setContentType("application/pdf"); response.setHeader("Content-Disposition", "attachment; filename="exported.pdf"); 

Ответ, в котором упоминается «плагин jQuery для запроса Ajax-файлов», заставил меня возглавить в правильном направлении, но это не сработало полностью для моей ситуации, поскольку у меня есть сложный объект и массив объектов, которые будут проходить в качестве критериев поиска / фильтровать данные. Я решил, что поделюсь своим кодом, если кто-то еще столкнется с этой ситуацией.

 $.download = function (url, data, method) { if (url && data) { //convert the data object into input HTML fields var inputs = ''; var convertToInput = function (key, keyStr, obj) { if (typeof obj === 'undefined') { return; } else if (typeof obj === "object") { for (var innerKey in obj) { if (obj.hasOwnProperty(innerKey)) { var innerKeyStr = ''; if (keyStr === '') { innerKeyStr = innerKey.toString(); } else { innerKeyStr = keyStr + "[" + innerKey.toString() + "]"; } convertToInput(innerKey, innerKeyStr, obj[innerKey]); } } return; } else if ($.isArray(obj)) { obj.forEach(function (item) { convertToInput(key, keyStr + "[]", item); }); return; } inputs += ""; }; convertToInput(null, '', data); //send request jQuery('
' + inputs + '
').appendTo('body').submit().remove(); }; }; $.download('/api/search?format=csv', searchData, 'POST');

Вероятно, это не имеет большого значения, но для обеспечения некоторого контекста у меня есть javascript и пользовательский интерфейс для нокаута в WebAPI, MVC4 и nHibernate. Часть `format = csv ‘строки запроса запускает MediaTypeFormatter для преобразования возвращенных моделей в тип файла CSV. Если я оставлю это, я верну модели обратно из API и смогу заполнить сетку Slick для отображения.

У меня была та же проблема, но на RESTFUL webservice использовать RESTFUL webservice для этого и иметь сложный объект данных, который я должен опубликовать.

Мое решение: подобно плагину jQuery, я создаю формуляр temp и отправлю его. Но я отправляю объект данных как параметр с содержимым json (я использую здесь AngularJS но он также должен работать с jQuery.param() .)

Javascript:

 $('
' + "" + '
').appendTo('body').submit().remove();

на стороне сервера мы используем CXF REST Service с поставщиком JACKSON :

Spring Config:

          

в controllerе я извлек параметр и преобразовал его обратно в Java Pojo:

 package de.controller; import javax.ws.rs.Consumes; import javax.ws.rs.FormParam; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import org.codehaus.jackson.map.ObjectMapper; import org.springframework.beans.factory.annotation.Autowired; @Path(Constants.PRINT_PATH) @Consumes({ MediaType.APPLICATION_JSON, "application/x-www-form-urlencoded"}) @Produces("application/pdf; charset=UTF-8") public class PrintRestController { @Autowired private PrintService printService; @POST @Produces("application/pdf") @Path("/pdf") public Response getPDF(@FormParam("data") String data) { return printService.getPDF(json2Versicherung(data)); } private Versicherung json2Versicherung(String data) { Versicherung lVersicherung = null; try { ObjectMapper mapper = new ObjectMapper(); lVersicherung = mapper.readValue(data, Versicherung.class); } catch(Exception e) { LOGGER.error("PrintRestController.json2Versicherung() error", e); } return lVersicherung; } } 

в PrintService я создаю pdf-файл и ответ:

 @Override public Response getPDF(Versicherung pVersicherung) { byte[] result = ... //build the pdf from what ever ResponseBuilder response = Response.ok((Object) result); response.header("Content-Disposition", "inline; filename=mypdf.pdf"); return response.build(); } 

Это решение работает для всех браузеров (даже для IE9, которые не могут обрабатывать URL-адреса данных), так и на планшетах и ​​смартфонах, и у него нет проблем с popupblockers

Плагин jQuery для запроса Ajax-подобных загрузок файлов – по существу – создание формы, добавление данных сообщения в виде скрытых полей, добавление их в тело страницы, отправку и удаление.

В моем случае у меня не было формы, и только кусок данных был опубликован как есть. Это было сделано для следующего решения. На стороне сервера я могу получить данные, просто прочитав параметр «data» из запроса и URI-декодирования.

 function postAndDownload(url, data) { encodedData = encodeURIComponent(data); $("
") .attr("action", url) .attr("method", "post") .append( $("input") .attr("type", "hidden") .attr("name", "data") .attr("value", encodedData) ) .appendTo("body") .submit() .remove(); };

Я не понимаю, почему вам нужен запрос ajax для URL-адреса загрузки файла! Но если это больше похоже на то, что клиент сам создает некоторый контент для загрузки – используйте данные uri. Прекрасно работает для Chrome и Firefox 20+. Safari и IE NOT! Если Flash разрешен, вы можете использовать загрузчик.

Ах, прочитав свой код, я вижу, что вы хотите отправить кучу параметров. Ну, если строка запроса слишком длинная (IE8- имеет ограничение 2083), почему бы просто не использовать якорь с правильным URL-адресом?

  $('a.export-csv').click( function (evt){ linkEl.attr('href','/export?' + encodeURIComponent(formQueryString())); return true; }); 

Вышеупомянутое позволяет вам изменить URL-адрес до события по умолчанию (щелчок).

Я думаю, что лучше всего будет создать файл temp pdf в папке с загрузками, а затем загрузить файл, используя всплывающее окно с iframe .. chrome будет загружать его мгновенно, но я полагаю, что для других вариантов Acrobat Reader должен быть установлен для просмотра pdf но опять же вы можете использовать FlashPaper тоже 🙂

  • Как сделать HTTP-запрос HTTP POST
  • Безопасность сообщений WCF без сертификата и windows auth
  • Как вы отправляете сообщение в iframe?
  • Почему метод GET быстрее, чем POST в HTTP?
  • Зашифрованы ли URL HTTPS?
  • HTTP-сервер тестирования, принимающий запросы GET / POST
  • Interesting Posts

    Какое аппаратное устройство использовало, чтобы съесть 1,4 ГБ моей 4 ГБ ОЗУ, и теперь внезапно после того, как никакие аппаратные изменения не съедят 2,2 ГБ?

    PowerPoint открывается на втором экране, но у меня нет ни одного

    Как заставить WRAP_CONTENT работать с RecyclerView

    Окончательный метод издевательств

    О форме-агностическом разрезе ndarrays

    Прозрачный слой windows, который является кликом и всегда остается на вершине

    Рандомизировать список

    Как изменить курсор Notepad ++

    Невозможно использовать Scanner.nextInt () и Scanner.nextLine () вместе

    Разрешение запрещается при доступе к общей папке VirtualBox, когда член группы vboxsf

    [Обозначение массива L – откуда оно взялось?

    Почему объектные объекты более объектно-ориентированные?

    Synaptics – Windows 8.1, обновление Synaptics не выполнено

    Самый быстрый способ вычисления 128-битного целого по модулю 64-разрядного целого числа

    Что такое 0x10 в инструкции по сборке «leal 0x10 (% ebx),% eax» x86?

    Давайте будем гением компьютера.