У меня есть одностраничный webapp, основанный на jquery. Он связывается с веб-службой RESTful через вызовы AJAX.
Я пытаюсь выполнить следующее:
- Отправьте POST, содержащий данные JSON, на URL REST.
- Если запрос указывает ответ JSON, возвращается JSON.
- Если запрос указывает ответ PDF/XLS/etc, возвращается возвращаемый двоичный файл.
Теперь у меня есть 1 и 2, а клиентское jquery-приложение отображает возвращенные данные на веб-странице, создавая элементы DOM на основе данных JSON. У меня также есть # 3, работающий с точки зрения веб-сервиса, то есть он будет создавать и возвращать двоичный файл, если заданы правильные параметры JSON. Но я не уверен, что лучший способ справиться с № 3 в коде JavaScript клиента.
Можно ли получить загружаемый файл обратно из вызова ajax, подобного этому? Как заставить браузер загружать и сохранять файл?
$.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;
}
});
Сервер отвечает на следующие заголовки:
Content-Disposition:attachment; filename=export-1282022272283.pdf
Content-Length:5120
Content-Type:application/pdf
Server:Jetty(6.1.11)
Другая идея - создать PDF файл и сохранить его на сервере и вернуть JSON, который содержит URL-адрес файла. Затем выполните другой вызов в обработчике успеха ajax, чтобы сделать что-то вроде следующего:
success: function(json,status) {
window.location.href = json.url;
}
Но это означает, что мне нужно будет сделать более одного вызова на сервер, и моему серверу нужно будет создавать загружаемые файлы, хранить их где-нибудь, а затем периодически очищать эту область хранения.
Должен быть более простой способ выполнить это. Идеи?
EDIT: после просмотра документов для $.ajax, я вижу, что ответ dataType может быть только одним из xml, html, script, json, jsonp, text
, поэтому я предполагаю, что нет способа напрямую загрузить файл с помощью запроса ajax, если только я не вставьте двоичный файл с использованием схемы URI данных, как это предложено в ответе @VinayC (чего я не хочу делать).
Итак, мои варианты:
-
Не используйте ajax и вместо этого отправляйте сообщение формы и вставляйте мои данные JSON в значения формы. Вероятно, нужно будет собечать со скрытыми iframe и т.д.
-
Не используйте ajax и вместо этого конвертируйте мои данные JSON в строку запроса для создания стандартного запроса GET и установите для этого URL window.location.href. Может понадобиться использовать event.preventDefault() в моем обработчике кликов, чтобы браузер не изменялся с URL-адреса приложения.
-
Используйте мою другую идею выше, но расширенную с предложениями от ответа @naikus. Отправьте запрос AJAX с некоторым параметром, который позволяет веб-службе знать, что это вызвано с помощью вызова ajax. Если веб-служба вызывается из вызова ajax, просто верните JSON с URL-адресом для сгенерированного ресурса. Если ресурс вызывается напрямую, тогда верните фактический двоичный файл.
Чем больше я думаю об этом, тем больше мне нравится последний вариант. Таким образом, я могу получить информацию о запросе (время генерации, размер файла, сообщения об ошибках и т.д.), И я могу действовать по этой информации перед началом загрузки. Недостатком является дополнительное управление файлами на сервере.
Какие-нибудь другие способы сделать это? Любые плюсы и минусы этих методов, о которых я должен знать?