前端文件下载的几种方式

随笔 James 1个月前 (09-18) 53次浏览 已收录 0个评论 扫描二维码

一、使用H5原生的download属性在html5中a标签多了一个属性download;没有添加download属性,用户点击a链接浏览器会打开并显示该链接的内容,若在a链接中加了download属性,点击该链接就不会打开这个文件,而是直接下载。

<a download="文件名" href="文件下载接口地址"></a>
// download属性值是下载后的文件名,href属性的值是后端文件下载接口地址
  • 只有 Firefox 和 Chrome 支持 download 属性。

  • download属性是html5中的a标签的新特性,与不支持h5的低版本浏览器不兼容!

  • 只能下载不能被浏览器打开的文件类型,如图片、文本文件、html文件这种可以被打开的文件,是无法被下载的

  • 如果需要下载的资源是跨域的,包含跨子域,在chrome浏览器下,使用download属性是可以下载的,但是不能重置下载的文件名;在FireFox浏览器下,download属性是无效的,也就是说火狐浏览器无论如何都不支持跨域资源的download属性下载。

  • 如果资源是同域名的,则chrome和火狐浏览器都是畅通无阻的下载,不会出现下载变浏览的情况

检测当前浏览器是否支持download属性

var isSupportDownload = 'download' in document.createElement('a')

二、借助H5 Blob实现文本信息文件下载
原理:将文本或者JS字符串信息借助Blob转换成二进制,然后,作为元素的href属性,配合download属性,实现下载。
代码示例如下(兼容Chrome和Firefox)

var downFile = function(content, fileName){
  // 创建隐藏的可下载的链接
  var eleLink = document.createElement('a');
  eleLink.download = fileName;
  eleLink.style.display = 'none';
  // 字符内容转变成blob地址
  var blob = new Blob([content]);
  // 将blob对象转化为BlobURL,使用a标签下载
  eleLink.href = URL.createObjectURL(blob);
  // 触发点击
  document.body.appendChild(eleLink);
  eleLink.click();
  //移除
  document.body.removeChild(eleLink);
}
var btnDom = document.getElementById('btn');
var textareaDom = document.getElementById('textarea');
if('download' in document.createElement('a')){
  // 作为test.html文件下载
  btnDom.addEventListener('click',function(){
    downFile(textareaDom.value, 'test.html')
  })
 } else {
   alert('浏览器不支持')
 }

其中,content指需要下载的文本或字符串内容,fileName指下载到系统中的文件名称
点击"下载"按钮,会把文本域中的内容全部作为一个.html后缀文件下载下来。
注意:理论上可以使用Blob对象下载任意类型的文件,毕竟都能转化为二进制文件,但目前主要用来存储文本文件。况且对于非文本文件或体积很大的文件,参数的传入是个问题。可以使用File对象。
三、借助Base64实现任意文件下载
对于非文本文件,也可以直接JS触发下载,例如我们想下载一张图片,可以把这张图片转换成base格式,然后下载。

function funDownload(domImg, fileName){
  // 创建隐藏的可下载的链接
  var eleLink = document.createElement('a');
  eleLink.download = fileName;
  eleLink.style.display = 'none';
  // 图片转base64地址
  var canvas = document.createElement('canvas');
  var context = canvas.getContext('2d');
  var width = domImg.naturalWidth;
  var height = domImg.naturalHeight;
  context.drawImage(domImg,0,0);
  // 如果是png图片,则canvas.toDataURL('image/png');
  eleLink.href = canvas.toDataURL('image/jpeg');
  // 触发点击
  document.body.appendChild(eleLink);
  eleLink.click();
  //移除
  document.body.removeChild(eleLink);
}

三、借助Base64实现任意文件下载
对于非文本文件,也可以直接JS触发下载,例如我们想下载一张图片,可以把这张图片转换成base格式,然后下载。

function funDownload(domImg, fileName){  // 创建隐藏的可下载的链接  var eleLink = document.createElement('a');  eleLink.download = fileName;  eleLink.style.display = 'none';  // 图片转base64地址  var canvas = document.createElement('canvas');  var context = canvas.getContext('2d');  var width = domImg.naturalWidth;  var height = domImg.naturalHeight;  context.drawImage(domImg,0,0);  // 如果是png图片,则canvas.toDataURL('image/png');  eleLink.href = canvas.toDataURL('image/jpeg');  // 触发点击  document.body.appendChild(eleLink);  eleLink.click();  //移除  document.body.removeChild(eleLink);}

不只是.html文件,.txt,.json等只要内容是文本的文件,都可以利用这种小技巧实现下载。

在chrome浏览器下,模拟点击创建的<a>元素即使不append到页面中,也是可以触发下载的,但是在火狐浏览器中却不行,因此上面的funDownload()方法有一个appendChild和removeChild的处理,就是为了兼容火狐浏览器。

四、Form表单实现下载功能

具体实现步骤:

1.给下载元素添加点击事件
2.创建form标签
3.通过input的type="hidden"来传递后台需要的参数
4.借助form的submit方法提交数据到后台实现下载功能

废话不多说,直接上代码

    <div id="commonDownload"></div>
    function formDownload(config) {
        config.url = setter.baseURL + config.url
         //1、专门设置一个空的div commonDownload,用于下载
        var $tempPane = $('#commonDownload')
        //2、新建一个form
        var $form = $('<form>')
        // form表单提交会刷新页面,因此绑定一个iframe,target设置之后将刷新转嫁到iframe。
        $form.attr({       id: 'downloadFile',       method: config.type,       action: config.url,       target: 'downloadFileTarget'     }).hide()
        // 3、填充你需要提交的参数
        for (var key in config.data) {      config.data[key] && $form.append('<input type="hidden" name="' + key + '" value="' + config.data[key] + '" />')    }
        //4、新建一个iframe    var $iframe = $('<iframe>')
        //此处需要设置name值用于form绑定。
        $iframe.attr({       id: 'downloadFileTarget',       name: 'downloadFileTarget'     }).hide()
        //5、将form填充到iframe里,再将iframe填充到tempPane里    $iframe.append($form)    $tempPane.append($iframe)
        //6、提交form表单
        $form.submit()
        //7、成功后清除tempPane里面的所有内容    $iframe.load = function () {      $tempPane.empty()     }  }


    老余博客, 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
    转载请注明原文链接:前端文件下载的几种方式
    喜欢 (3)
    []
    分享 (0)
    发表我的评论
    取消评论
    表情 贴图 加粗 删除线 居中 斜体

    Hi,您需要填写昵称和邮箱!

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址