不同场景下的多种文件下载方案实践 您所在的位置:网站首页 通过a标签下载文件 不同场景下的多种文件下载方案实践

不同场景下的多种文件下载方案实践

2024-02-12 15:29| 来源: 网络整理| 查看: 265

文件下载实践方案汇总

前端开发中 常用 到的下载方式:

a标签下载(链接下载) fetch / axios / XMLHttpRequest 异步请求资源下载 blob 下载 FileSaver 第三方库下载

除了以上几种通用性方案,在JQuery时期还会经常使用到 form 表单提交等方式,但是随着Vue、React的兴起,一般在进行选型时便很少使用form表单提交的形式了。

方案1:a标签下载

简单下载方式,通过a标签的href属性加载下载url,适合普通场景下的简单下载。 MDN:flowus.cn/45383ad9-23…

👏 适合场景

get 请求

返回为文件流 / 返回URL

🚫 不适合场景

下载需要计算、权限验证、携带Cookie

需要动态生成文件内容,即需要Post传参

需要处理跨域问题

需要处理大文件下载(10M以上)

需要断点续传或文件下载进度监控等

⌨️ 应用示例 下载图片 function downLoadFile(res){ const ele = document.createElement('a'); ele.setAttribute('href',res.url); //设置下载文件的url地址 ele.setAttribute('download' , 'download');//用于设置下载文件的文件名 ele.click(); link.addEventListener('click', (event) => { event.preventDefault(); const downloadTimer = setTimeout(() => { alert('下载超时,请重试!'); }, 5000); const errorListener = () => { clearTimeout(downloadTimer); alert('下载失败!'); link.removeEventListener('error', errorListener); }; link.addEventListener('error', errorListener); }); } window.onload = function(){ $.ajax({ url:"api/file/download", type:"get", dataType:'JSON' }).then(function(res){ if(res.bizNO > 0 ){ downLoadFile(res); }else{ alert(res.bizMsg); } }).always(function(){ alert("连接异常"); }) } 💡 扩展说明

关于优先级

Causes the browser to treat the linked URL as a download. Can be used with or without a filename value:

Without a value, the browser will suggest a filename/extension, generated from various sources:

The [Content-Disposition](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition) HTTP header → 上面的demo示例中,即使设置了dowmload属性,由于响应头中包含 Content-Disposition:attachment;filename="neom-xDQKvPjxtxo-unsplash.jpg",所以下载图片名称以响应头为准

filename: defining a value suggests it as the filename. / and \ characters are converted to underscores (_). Filesystems may forbid other characters in filenames, so browsers will adjust the suggested name if necessary.

关于响应头Content-Disposition

Content-Disposition 是一个 HTTP 响应头,它指定了如何显示响应的内容,特别是对于以附件形式下载的文件。这个头部可以包含一个内联展示(inline)的选项,也可以包含一个附件(attachment)的选项,以及可选的文件名参数。

主要作用如下:

内联展示(inline)

如果Content-Disposition头部的值设置为inline,浏览器通常会尝试在浏览器窗口内显示内容,例如在浏览器中直接打开 PDF 文件或图像。

这对于一些直接浏览的文件类型是合适的。

附件下载(attachment)

如果Content-Disposition头部的值设置为attachment,浏览器通常会提示用户下载文件,而不是直接在浏览器中显示。

这对于需要用户保存到本地的文件,如文档、图像、音频和视频等,是常见的设置。

指定文件名

通过filename参数,可以指定下载文件的文件名。这对于确保用户下载的文件有一个明确的名称非常有用,而不是使用服务器上的默认文件名。

例如,Content-Disposition: attachment; filename="example.txt"。 在这里插入图片描述

方案2: Blob 下载 👏 基础概念 什么是blob blob是File类的超类,表示 二进制大对象,是JS对不可修改二进制数据的封装类型 blob相关知识点 developer.mozilla.org/zh-CN/docs/… 在这里插入图片描述 👏 适合场景

接口返回的格式为文件流格式

下载需要计算、权限验证、携带Cookie

需要动态生成文件内容,即需要Post传参

👏 代码实现 function fileDownLoad(data){ // 1. 创建点击下载的元素 var linkElement = document.createElement('a'); // 2. 判断浏览器是否支持blob对象 try{ //该实例化的方式第一个参数必须是数组的格式 var blob = new Blob([data],{ type: "application/pdf" }); }catch(e){ //旧版本浏览器下的blob创建对象 window.BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder; if(e.name == 'TypeError' && window.BlobBuilder){ var blobbuilder = new BlobBuilder(); BlobBuilder.append(data); var blob = blobbuilder.getBlob("application/pdf"); }else{ alert("浏览器版本较低,暂不支持该文件类型下载"); } } // 提取blob文件中的url信息,使二进制文件在不读取到js中时直接下载 let url = window.URL.createObjectURL(blob); linkElement.setAttribute('href',url); linkElement.setAttribute('downLoad','download'); linkElement.click(); // 释放URL内存 window.URL.revokeObjectURL(url); } document.querySelector('#fileInput').addEventListener('change', (event)=>{ fileDownLoad(event.target.files[0]) }) 下载接口需要携带Cookie信息 function downloadFileWithToken(url, token) { let xhr = new XMLHttpRequest(); xhr.open('GET', url, true); xhr.setRequestHeader("Authorization", token); xhr.responseType = 'blob'; xhr.onload = function (e) { if (this.status === 200) { let blob = this.response; let fileName = '下载的文件名称'; // 针对IE浏览器 if (window.navigator.msSaveBlob) { try { window.navigator.msSaveBlob(blob, fileName); } catch (e) { console.log(e); } } else { // 通用浏览器 const url = window.URL.createObjectURL(blob); a.href = url; a.download = fileName; document.body.appendChild(a); a.click(); document.body.removeChild(a); window.URL.revokeObjectURL(url); } } else { alert('下载文件失败'); } } xhr.send(); } 方案3:FileSaver实现 基础介绍

FileSaver.js 是一个用于在客户端保存文件的 JavaScript 库

github.com/eligrey/Fil…

基础使用 import FileSaver from 'file-saver' let blob = new Blob(["Hello, FileSaver! Blob 下载"], {type: "text/plain;"}); window.saveAs(blob, "hello FileSaver.txt"); import FileSaver from 'file-saver' let blob = new Blob(["Hello, FileSaver! URL 下载"], {type: "text/plain;charset=utf-8"}); const url = window.URL.createObjectURL(blob) window.saveAs(url, "hello FileSaver.txt"); 原理介绍

在这里插入图片描述

欢迎补充其他实现思路



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有