浏览器文件下载

【浏览器文件下载】

主要原理

前端

<!-- 其中的 download 提示浏览器下载而不是打开 -->
<a href="http://xxxx.com/yyy.txt" downlod="yyy.txt"></a>

后端

后端的设置主要是为了当浏览不支持 download 属性的时候的兼容性。

res.setContentType("application/octet-stream");
res.addHeaders("Content-Disposition", "attachment;filename=" + filename);
res.addHeaders("Content-Length", content.length);

参考

推荐的 a 标签的方式

/**
 * @param {string} url 下载链接
 * @param {string} filename 保存到本地的文件名
 */
var fileDownload = function(url, filename) {
    
    var hiddenALink = document.createElement('a');
    
    // 设置下载链接
    hiddenALink.href = url;
    // 设置保存到本地的文件名
    hiddenALink.download = filename;
    // 设置在页面上不显示
    hiddenALink.style.display = 'none';

    // 因为 Firefox 兼容性问题,必须要 append 到页面
    document.body.appendChild(hiddenALink);
    hiddenALink.click(); // 点击操作
    document.body.removeChild(hiddenALink);
}

在 Chrome 中 appendChild(hiddenALink) 的操作可以省去直接 click(),但是在 FireFox 中却不可以,必须要 appendChild() 才可以 click(),具体可参考 stackoverflow programmatical-click-on-a-tag-not-working-in-firefox

优点

  • 简单,直观,方便

缺点

  • 需要传递较多参数时略麻烦
  • 某些情况下的鉴权会不可用

当点击下载,出现的却是 html 文件或者 json 文件的时候,考虑下是不是要放开后端的 security 匿名访问。

ajax blob 形式下载

/**
 * 不管是用的原生的 XMLHttpRequest 还是 axios 封装好的
 * 
 * 其最主要的一个点是 responseType: 'blob'
 */
var fileDownload = function(url, filename) {

    axios.get(url, {
        // 这里可以添加其他参数
        // 比如用于筛选数据的,鉴权的
        responseType: 'blob'
    }).then(res => {
        // 此时是已经下载完了的内容
        // 如果在下载过程中,没有关于进度的处理,将没有任何提示
        // 小文件速度很快,几乎无影响,大文件会有一段儿时间的,无反应等待
        // axios 的 res 里的 data 才是 blob 的内容
        const content = res.data;

        // 这里把下载完的内容,搞成了 ObjectURL
        const furl = window.URL.createObjectURL(content);

        // 到这里又可以调用上面那个 a 标签的方式了
        download0(furl, filename);
    })
}

/**
 * 这就是上面 a 标签那个
 *
 * @param {string} url 下载链接
 * @param {string} filename 保存到本地的文件名
 */
var download0 = function(url, filename) {

    var a = document.createElement('a');
    
    a.href = url;
    a.download = filename;
    a.style.display = 'none';

    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
}

优点

  • 传递参数方便

缺点

  • 超大文件的时候,对客户端的内存不友好
  • 超大文件在页面没有做关于下载进度处理的情况下,看不到下载进度,体验不友好

适用场景

  • 小文件
  • 需要传递较多参数
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lixifun

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值