У меня есть одностраничное веб-приложение на основе 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;
}
Но это означает, что мне нужно будет сделать более одного вызова на сервер, и мой сервер должен будет создавать загружаемые файлы, хранить их где-то, а затем периодически очищать эту область хранения.
Должен быть более простой способ сделать это. Идеи?
РЕДАКТИРОВАТЬ: После просмотра документов для $ .ajax, я вижу, что dataType ответа может быть только один из xml, html, script, json, jsonp, text
, поэтому я предполагаю, что нет способа напрямую загрузить файл с помощью запроса AJAX, если я не внедрить двоичный файл с использованием схемы Data URI, как предложено в ответе @VinayC (что я не хочу делать).
Итак, я думаю, мои варианты:
Не используйте ajax, вместо этого отправьте сообщение формы и вставьте мои данные JSON в значения формы. Вероятно, придется возиться со скрытыми iframes и тому подобное.
Не использовать ajax, а вместо этого преобразовать мои данные JSON в строку запроса для создания стандартного запроса GET и установить для window.location.href этот URL. Может потребоваться использовать event.preventDefault () в моем обработчике кликов, чтобы браузер не менял URL приложения.
Используйте мою другую идею выше, но дополненную предложениями из ответа @naikus. Отправьте AJAX-запрос с некоторым параметром, который позволяет веб-сервису узнать, что он вызывается через AJAX-вызов. Если веб-служба вызывается из вызова ajax, просто верните JSON с URL-адресом сгенерированного ресурса. Если ресурс вызывается напрямую, верните фактический двоичный файл.
Чем больше я об этом думаю, тем больше мне нравится последний вариант. Таким образом, я могу получить информацию о запросе (время генерации, размер файла, сообщения об ошибках и т. Д.), И я могу обработать эту информацию перед началом загрузки. Недостатком является дополнительное управление файлами на сервере.
Есть ли другие способы сделать это? Какие-нибудь плюсы / минусы этих методов мне следует знать?