У меня есть одностраничное веб-приложение на основе 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, если я не внедряю двоичный файл в использование Схема URI данных, предложенная в ответе @VinayC (что я не хочу делать).
Итак, я думаю, что мои варианты:
Не используйте ajax, вместо этого отправьте сообщение формы и вставьте мои данные JSON в значения формы. Вероятно, придется возиться со скрытыми фреймами и тому подобное.
Не используйте ajax, а вместо этого преобразуйте мои данные JSON в строку запроса для создания стандартного запроса GET и задайте для window.location.href этот URL. Может потребоваться использовать event.preventDefault () в моем обработчике кликов, чтобы браузер не менял URL приложения.
Используйте мою другую идею выше, но дополненную предложениями из ответа @naikus. Отправьте запрос AJAX с некоторым параметром, который позволяет веб-сервису узнать, что он вызывается с помощью вызова ajax. Если веб-служба вызывается из вызова ajax, просто верните JSON с URL-адресом сгенерированного ресурса. Если ресурс вызывается напрямую, верните фактический двоичный файл.
Чем больше я об этом думаю, тем больше мне нравится последний вариант. Таким образом, я могу получить информацию о запросе (время генерации, размер файла, сообщения об ошибках и т. Д.), И я могу обработать эту информацию перед началом загрузки. Недостатком является дополнительное управление файлами на сервере.
Есть ли другие способы сделать это? Какие-нибудь плюсы / минусы этих методов я должен знать?
url = 'http://localhost/file.php?file='+ $('input').val(); window.open(url);
Простой способ получить те же результаты. Поместите заголовок в файл php. Не нужно отправлять ajax или получать запросы