Загрузите PDF-файл, используя jquery ajax
Я хочу скачать PDF-файл для ответа jquery ajax. Ответ Ajax содержит данные файла PDF. Я попробовал это решение. Мой код указан ниже, но я всегда получаю пустой PDF.
$(document).on('click', '.download-ss-btn', function () {
$.ajax({
type: "POST",
url: 'http://127.0.0.1:8080/utils/json/pdfGen',
data: {
data: JSON.stringify(jsonData)
}
}).done(function (data) {
var blob = new Blob([data]);
var link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = "Sample.pdf";
link.click();
});
});
5 ответов
У jQuery есть некоторые проблемы с загрузкой двоичных данных с использованием запросов AJAX, поскольку он еще не реализует некоторые возможности HTML5 XHR v2, см. этот запрос на усовершенствование и это обсуждение
Учитывая это, у вас есть одно из двух решений:
Первое решение, отказаться от JQuery и использовать XMLHTTPRequest
Перейти с нативным HTMLHTTPRequest, вот код, чтобы сделать то, что вам нужно
var req = new XMLHttpRequest();
req.open("GET", "/file.pdf", true);
req.responseType = "blob";
req.onload = function (event) {
var blob = req.response;
console.log(blob.size);
var link=document.createElement('a');
link.href=window.URL.createObjectURL(blob);
link.download="Dossier_" + new Date() + ".pdf";
link.click();
};
req.send();
Второе решение, используйте плагин jquery-ajax-native
Плагин может быть найден здесь и может быть использован для возможностей XHR V2, отсутствующих в JQuery, вот пример кода, как его использовать
$.ajax({
dataType: 'native',
url: "/file.pdf",
xhrFields: {
responseType: 'blob'
},
success: function(blob){
console.log(blob.size);
var link=document.createElement('a');
link.href=window.URL.createObjectURL(blob);
link.download="Dossier_" + new Date() + ".pdf";
link.click();
}
});
Я новичок, и большая часть кода из поиска Google. Я получил мою PDF-загрузку, работающую с кодом ниже (пробная версия и игра с ошибками). Спасибо за подсказки кода (xhrFields) выше.
$.ajax({
cache: false,
type: 'POST',
url: 'yourURL'
contentType: false,
processData: false,
data: yourdata,
//xhrFields is what did the trick to read the blob to pdf
xhrFields: {
responseType: 'blob'
},
success: function (response, status, xhr) {
var filename = "";
var disposition = xhr.getResponseHeader('Content-Disposition');
if (disposition) {
var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
var matches = filenameRegex.exec(disposition);
if (matches !== null && matches[1]) filename = matches[1].replace(/['"]/g, '');
}
var linkelem = document.createElement('a');
try {
var blob = new Blob([response], { type: 'application/octet-stream' });
if (typeof window.navigator.msSaveBlob !== 'undefined') {
// IE workaround for "HTML7007: One or more blob URLs were revoked by closing the blob for which they were created. These URLs will no longer resolve as the data backing the URL has been freed."
window.navigator.msSaveBlob(blob, filename);
} else {
var URL = window.URL || window.webkitURL;
var downloadUrl = URL.createObjectURL(blob);
if (filename) {
// use HTML5 a[download] attribute to specify filename
var a = document.createElement("a");
// safari doesn't support this yet
if (typeof a.download === 'undefined') {
window.location = downloadUrl;
} else {
a.href = downloadUrl;
a.download = filename;
document.body.appendChild(a);
a.target = "_blank";
a.click();
}
} else {
window.location = downloadUrl;
}
}
} catch (ex) {
console.log(ex);
}
}
});
Вы можете сделать это с помощью html5 очень легко:
var link = document.createElement('a');
link.href = "/WWW/test.pdf";
link.download = "file_" + new Date() + ".pdf";
link.click();
link.remove()
Для тех, кто ищет более современный подход, вы можете использовать fetch API
. В следующем примере показано, как загрузитьPDF
файл. Это легко сделать с помощью следующего кода.
fetch(url, {
body: JSON.stringify(data),
method: 'POST',
headers: {
'Content-Type': 'application/json; charset=utf-8'
},
})
.then(response => response.blob())
.then(response => {
const blob = new Blob([response], {type: 'application/pdf'});
const downloadUrl = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = downloadUrl;
a.download = "file.pdf";
document.body.appendChild(a);
a.click();
})
Я считаю, что этот подход намного легче понять, чем другие XMLHttpRequest
решения. Кроме того, он имеет синтаксис, аналогичныйjQuery
подход, без необходимости добавлять какие-либо дополнительные библиотеки.
Конечно, я бы посоветовал проверить, для какого браузера вы разрабатываете, поскольку этот новый подход не будет работать в IE. Вы можете найти полный список совместимых браузеров по следующей [ссылке][1].
Важно: в этом примере я отправляю запрос JSON на сервер, прослушивающий данныйurl
. Этаurl
должен быть установлен, на моем примере я предполагаю, что вы знаете эту часть. Также обратите внимание на заголовки, необходимые для работы вашего запроса. Поскольку я отправляю JSON, я должен добавитьContent-Type
заголовок и установите для него application/json; charset=utf-8
, чтобы сообщить серверу, какой тип запроса он получит.
Попробуй это:
$(document).on('click', '.download-ss-btn', function () {
$.ajax({
type: "POST",
url: 'http://127.0.0.1:8080/utils/json/pdfGen',
data: {
data: JSON.stringify(jsonData)
},
headers: {
'Content-Type': 'application/json; charset=utf-8'
}
}).done(function (data) {
let binaryString = window.atob(data);
let binaryLen = binaryString.length;
let bytes = new Uint8Array(binaryLen);
for (let i = 0; i < binaryLen; i++) {
let ascii = binaryString.charCodeAt(i);
bytes[i] = ascii;
}
var blob = new Blob([data], {type: "application/pdf"});
var link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = "Sample.pdf";
link.click();
});
});