如何获取Django返回的可下载文件名?
解决Django FileResponse文件名前端无法获取的问题
问题原因
浏览器Fetch API默认仅暴露部分安全响应头(如Content-Type),Content-Disposition不在默认暴露列表内,因此前端直接调用response.headers.get('Content-Disposition')会返回null,需服务器端配置允许暴露该响应头。
解决方案
1. 修改Django视图,配置响应头
在返回FileResponse时,添加Access-Control-Expose-Headers头,明确允许前端访问Content-Disposition:
def your_view(request): # ... 业务逻辑处理 ... response = FileResponse(protected_pdf_file, as_attachment=True, filename='result.pdf') # 允许前端获取Content-Disposition头 response['Access-Control-Expose-Headers'] = 'Content-Disposition' return response
如果项目使用django-cors-headers处理跨域,也可在全局配置中添加:
# settings.py CORS_EXPOSE_HEADERS = ['Content-Disposition']
2. 前端修改代码,解析文件名
调整Fetch逻辑,先获取并解析Content-Disposition头,再处理响应数据:
function ajaxSend(url, data) { fetch(url, { method: 'POST', body: data, }) .then(response => { // 初始化默认文件名 let filename = 'result.pdf'; // 获取并解析Content-Disposition头 const contentDisposition = response.headers.get('Content-Disposition'); if (contentDisposition) { const matches = contentDisposition.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/); if (matches?.[1]) { filename = matches[1].replace(/['"]/g, ''); } } // 根据响应类型处理数据 const contentType = response.headers.get('Content-Type'); const dataPromise = contentType === 'application/json' ? response.json() : response.blob(); // 返回数据与文件名的组合 return Promise.all([dataPromise, filename]); }) .then(([data, filename]) => { if (data instanceof Blob) { const url = URL.createObjectURL(data); download_link.href = url; download_link.download = filename; // 填入解析到的文件名 download_link.style.display = 'block'; } else { block_msg.textContent = data.message; } }) .catch(error => console.error(error)) }
关键说明
- 正则表达式
/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/可匹配带引号或不带引号的filename参数。 - 设置默认文件名
result.pdf,避免解析失败时下载功能异常。
内容的提问来源于stack exchange,提问作者Mikhailo
相关产品推荐
相关产品推荐

