当前位置: 首页 > news >正文

通用下载方法

/** * 通用下载方法 * @param {string} url - 下载地址 * @param {object} params - 请求参数(POST时作为请求体,GET时作为查询参数) * @param {string} filename - 下载文件名(可选,不传时从响应头Content-Disposition自动提取) * @param {object} config - 请求配置(可选,可传入 method 指定请求方式,默认 post) * @param {boolean} showLoading - 是否显示加载动画(默认 true) * @returns {Promise} - 返回 Promise */ export function download(url, params, filename, config, showLoading = true) { // 显示下载加载动画 if (showLoading) { downloadLoadingInstance = ElLoading.service({ text: "正在下载数据,请稍候", background: "rgba(0, 0, 0, 0.7)" }) } // 从配置中获取请求方式,默认为 POST const method = (config && config.method) || 'post' // 构建请求配置,强制设置 responseType 为 blob 用于文件下载 const requestConfig = { responseType: 'blob', ...config } // 删除 method 属性,避免传递给 axios delete requestConfig.method let requestPromise // 根据请求方式选择 GET 或 POST if (method === 'get') { // GET 请求:参数通过 params 传递(查询参数) requestConfig.params = params requestPromise = service.get(url, requestConfig) } else { // POST 请求:参数作为请求体,使用表单编码 requestPromise = service.post(url, params, { transformRequest: [(params) => { return tansParams(params) }], headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, ...requestConfig }) } return requestPromise.then(async (response) => { // 响应格式为 { data: blobData, headers: responseHeaders } const blobData = response.data const headers = response.headers // 验证响应是否为 Blob 类型 const isBlob = blobValidate(blobData) if (isBlob) { // 将响应数据转为 Blob 对象 const blob = new Blob([blobData]) // 确定最终文件名:优先使用传入的 filename,否则从响应头提取 let finalFilename = filename if (!finalFilename && headers && headers['content-disposition']) { // 解析 Content-Disposition 响应头获取文件名 const disposition = headers['content-disposition'] const match = disposition.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/) if (match && match[1]) { finalFilename = decodeURIComponent(match[1].replace(/['"]/g, '')) } } // 使用 file-saver 保存文件 saveAs(blob, finalFilename) } else { // 如果不是 Blob,说明是错误响应,解析错误信息 const resText = await blobData.text() const rspObj = JSON.parse(resText) const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default'] ElMessage.error(errMsg) } // 关闭加载动画 if (showLoading && downloadLoadingInstance) { downloadLoadingInstance.close() } }).catch((r) => { // 捕获下载异常 console.error(r) ElMessage.error('下载文件出现错误,请联系管理员!') // 关闭加载动画 if (showLoading && downloadLoadingInstance) { downloadLoadingInstance.close() } }) }

用法

const url = `/annotation/model/config/download?modelKey=${model.modelKey}`; download(url, {}, undefined, { method: 'get' }, false).then(() => { proxy.$modal.msgSuccess("下载配置文件成功"); });
http://www.jsqmd.com/news/1153269/

相关文章:

  • 3分钟永久备份B站视频:m4s-converter让缓存视频永不失效的完整指南
  • 【新手快速上手】 OpenClaw 本地离线 AI 智能体 Windows 搭建实操手册(含安装包)
  • 拥抱 Markdown 带来的奇妙世界
  • Ansys Workbench 屈曲分析:特征值 vs 非线性 5大核心差异与工程选型指南
  • Cesium@1.138中实现标尺绘制功能
  • quartus与vivado 的debug标记代码对比
  • NVIDIA Profile Inspector终极指南:如何解决驱动兼容性崩溃问题
  • 计算机毕业设计之基于SSM框架的医院信息管理系统设计与实现
  • 深度解析NVIDIA Profile Inspector在571.96驱动版本中的内存访问异常与修复方案
  • 从故事点到概率分布:用贝叶斯模型重塑项目工期估算的决策质量
  • 合肥七七音响亲测,2026年7月效果超赞
  • 别再为懒惰找借口!居家也能练出“超模感”,这套方案建议锁死!
  • 火龙果矮砧密植,水肥一体滴灌系统搭建实战指南(配套图解)
  • 完整学习LLM(一):为什么我要系统学习大模型
  • 客服效率提升实战|智能400电话全功能落地教程:低成本搭建企业标准化客服体系
  • 应用宝 MMTLS 协议与wx_code分析
  • 嵌入式多层 PCB 层叠设计完全指南:四层板信号回流路径与阻抗控制核心要点
  • 【供应链底座】如何通过“设备物模型”与“流体力学正向研发”重构工业管网:自控阀门源头工厂选型及全球化信任特征全栈解析
  • 5分钟掌握网易游戏资源解包神器unnpk:轻松探索阴阳师等游戏内部世界
  • 全球市场研究服务网络是什么?主要有哪些要素与对出海企业的应用?
  • 决策树 vs 随机森林 vs XGBoost:3 大集成学习算法性能对比与选型指南
  • 基于RFID及GIS技术的资产管理系统设计与应用
  • 【RT-DETR涨点改进】14 尺度自适应位置编码:让RT-DETR不再“看不清”小目标
  • 陈,小动物气体代谢监测系统 动物气体能量代谢系统 小动物能量代谢监测系统
  • 使用堡垒机构建运维安全网关——JumpServer堡垒机的安装部署实践教程
  • 深入理解MySQL_10 Explain的用法
  • Ubuntu 18.04深度学习驱动安装避坑指南:NVIDIA 418驱动选型与nouveau禁用
  • 为什么中国自家的“codex”和“claude code”,没什么人用?
  • 终极指南:用DDrawCompat在现代Windows系统复活经典DirectX游戏 [特殊字符]
  • d2dx:暗黑破坏神2的现代化重生之旅,让经典在2026年依然闪耀