如何在Django模板中使用jQuery捕获PDF下载的GET请求事件并实现模态框自动关闭
这个问题我之前也碰到过,你用的Ajax方案之所以没法触发PDF下载,是因为浏览器只会对直接的导航请求(比如点击a标签跳转、表单提交)自动触发下载行为,Ajax拿到响应数据后不会主动帮你做这件事。下面给你两种可行的解决方案:
方案一:用隐藏iframe发起下载(推荐,无需修改后端) #
这种方法的思路是:点击按钮时先显示模态框,然后创建一个隐藏的iframe来发起下载请求,当iframe加载完成(也就是后端返回了PDF文件),就关闭模态框。
修改你的JavaScript代码如下:
$("#pdf-button").on("click", function(event) { // 阻止a标签的默认跳转行为 event.preventDefault(); const downloadUrl = $(this).attr('href'); // 显示"报告处理中"模态框 $('#myPDFModal').modal('show'); // 创建隐藏的iframe元素 const iframe = document.createElement('iframe'); iframe.style.display = 'none'; iframe.src = downloadUrl; // 监听iframe的加载完成事件,关闭模态框并清理iframe iframe.onload = function() { $('#myPDFModal').modal('hide'); document.body.removeChild(iframe); // 兼容部分浏览器的readyState变化事件 iframe.onreadystatechange = function() { if (iframe.readyState === 'complete') { $('#myPDFModal').modal('hide'); document.body.removeChild(iframe); // 将iframe添加到页面中,触发下载请求 document.body.appendChild(iframe);
这种方案的优势是不需要修改后端代码,逻辑简单,而且能准确捕捉到后端处理完成并返回文件的时机,模态框会在合适的时候关闭。
方案二:用Ajax获取Blob并手动触发下载 #
如果需要更精细的控制(比如处理下载失败的情况),可以用Ajax获取PDF的二进制数据,转成Blob后手动创建下载链接,完成后关闭模态框。
需要确保后端返回的响应头包含
Content-Type: application/pdf
和
Content-Disposition: attachment; filename="你的文件名.pdf"
,这样前端才能正确处理文件名。
代码示例:
$("#pdf-button").on("click", function(event) {
event.preventDefault();
const downloadUrl = $(this).attr('href');
$('#myPDFModal').modal('show');
$.ajax({
url: downloadUrl,
type: 'GET',
// 指定响应类型为Blob,用于处理二进制文件
xhrFields: {
responseType: 'blob'
}).done(function(blobData) {
// 创建临时下载链接
const downloadLink = document.createElement('a');
const objectUrl = window.URL.createObjectURL(blobData);
downloadLink.href = objectUrl;
// 从响应头中解析文件名(如果后端设置了的话)
const contentDisposition = this.getResponseHeader('Content-Disposition');
let filename = 'report.pdf';
if (contentDisposition) {
const filenameMatch = contentDisposition.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/);
if (filenameMatch && filenameMatch[1]) {
filename = decodeURIComponent(filenameMatch[1].replace(/['"]/g, ''));
downloadLink.download = filename;
// 触发下载
document.body.appendChild(downloadLink);
downloadLink.click();
// 清理临时资源
window.URL.revokeObjectURL(objectUrl);
document.body.removeChild(downloadLink);
// 关闭模态框
$('#myPDFModal').modal('hide');
}).fail(function() {
// 处理下载失败的情况