资讯专栏INFORMATION COLUMN

[ 一起学React系列 -- 9 ] React中的文件下载

Jacendfeng / 2064人阅读

摘要:本篇所说的文件下载也是基于和或者都行。的返回值是一个有意思的对象,它包含了很多方法,其中一个方法就是。通过的响应头获取到文件名。接下来就是对标签的一系列操作,然后模拟点击事件触发下载动作。

距离上次博文更新已经快一个月了,期间忙于各种事情无法脱身。今天难得闲暇 and then 就来更新啦...
上篇中我们了解了下载React中如何实现文件的上传,虽然不算什么高大上的技术但实际开发的时候会让自己更加的游刃有余。今天继续更新另一个相关的技术 --> 文件的下载
看过上篇博文的朋友应该有印象,做文件上传的功能可以用Form表单fetch(Ajax或者Axios都行)和Form+fetch这三个方法。后台采用express框架,由于fetch请求会涉及到跨域问题,所以后台还使用了Cors中间件来解决跨域的问题。这一点在上篇博文中都有提及所以在这里就不加赘述。
本篇所说的文件下载也是基于Formfetch(Ajax或者Axios都行)。且听慢慢道来...

Form

Form表单可谓是前端界的万金油,什么数据提交、上传下载都样样精通,最关键的是:不需要考虑跨域
利用Form表单进行文件下载很简单,只需要几行代码就可以搞定:

class FormDownload extends Component {
    render() {
        return (
            
) } } export default FormDownload;

只要这一小段代码就可以实现文件的下载,是不是很开森?

Fetch

利用Fetch实现文件下载相比于Form那就显得很麻烦也很啰嗦,为什么呢?上代码先

class FetchDownload extends Component {
    download = () => {
        fetch("http(s)://下载文件的后台接口").then(res => res.blob().then(blob => {
            let a = document.createElement("a");
            let url = window.URL.createObjectURL(blob);
            let filename = res.headers.get("Content-Disposition");
            if (filename) {
                filename = filename.match(/"(.*)"/)[1]; //提取文件名
                a.href = url;
                a.download = filename; //给下载下来的文件起个名字
                a.click();
                window.URL.revokeObjectURL(url);
                a = null;
            }
        }));
    };

    render() {
        return (
            
        )
    }
}

export default FetchDownload;

麻烦在哪儿:

1、需要考虑跨域问题
2、需要对返回值进行转化
3、需要有DOM操作(生成a标签和销毁a标签)

下面就一起来看看具体操作步骤:

用fetch访问后台接口并接受后台返回值。因为fetch方法返回一个Promise对象,因此我们可以在then用获取到它的返回值

这一步就厉害了。fetch的返回值是一个有意思的对象,它包含了很多方法,其中一个方法就是blob()。这个方法可以将fetch的返回值转化成Blob对象。

利用document.createElement创建一个a标签

利用window.URL.createObjectURL将blob数据转成对应url

通过fetch的响应头获取到文件名res.headers.get("Content-Disposition")。这里需要mark下,因为我们后台使用了Cors中间件来解决跨域问题,因此需要做特别的设置来让Cors将响应头给暴露出来"exposedHeaders": "*",具体的大家可以看后台代码。

接下来就是对a标签的一系列操作,然后模拟点击事件触发下载动作。

最后需要将转化出来的url进行销毁window.URL.revokeObjectURL(url),a标签置为null

看完整个过程,除了了解到前面所说的麻烦,我们依然要看到其优点所在。对于Form实现的下载功能,我们只能做下载,而不能做额外的事情;但是使用fetch我们可以将获取到的数据做更多的处理,自由度相对较高。

总结

目前这方面的轮子特别多而且很是花里胡哨(但是用的特别爽,真香系列!),不过最基础的往往也就这么点技术。万丈高楼平地起,学好基础何怕不会造轮子。。。哈哈。另外再把demo贴一下,有兴趣的同学可以下载下来跑一下溜溜

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/108807.html

相关文章

  • [ 一起React系列 -- 8 ] React中的文件上传

    摘要:前言本期的主题是在中如何实现文件上传。文件上传解决方案目前比较主流的解决方案就是表单或者和表单来实现。文件上传解决方案表单利用表单组件进行文件上传是远古时期就一直在用的方法而且还真经久不衰,厉害了。 终于抽出时间来继续更新自己的博客,最近忙得够呛...对于该系列博客不知道大家有没有这样的看法,对于React常见的基础东西并没有过多或者详细列出,感觉有点不符合系列标题。的确,笔者一开始也...

    Travis 评论0 收藏0
  • [ 一起React系列 -- 12 ] React-Router4 (2)

    摘要:验证路由所谓的验证路由其实就是该路由的外层加了一层验证机制,有授权的用户才能进入,反之都无法进入。一起学系列也随着这篇的结束而告一段落了。大家一起加油最后再献上和本篇博文有关的代码链接和示例页面 时隔那么久,博主终于从睡梦中醒来开始更新博客啦!为自己的勤劳欢呼...(pia pia pia打脸)!本次我们接着上一篇博客继续聊React-Router4。上篇我们主要了解了React-Ro...

    chaos_G 评论0 收藏0
  • [ 一起React系列 -- 11 ] React-Router4 (1)

    摘要:中的包中的包主要有三个和。的理念上面提到的理念是一切皆组件以下统一称组件。从这点来说的确方便了不少,也迎合一切皆组件的理念。组件是中主要的组成单位,可以认为是或的路由入口。将该标示为严格匹配路由。的属性追加一条。 2019年不知不觉已经过去19天了,有没有给自己做个总结?有没有给明年做个计划?当然笔者已经做好了明年的工作、学习计划;同时也包括该系列博客剩下的博文计划,目前还剩4篇:分别...

    tinysun1234 评论0 收藏0
  • [ 一起React系列 -- 3 ] UI的扩展数据源Props以及Props约束

    摘要:所以还是印证那句话是组件渲染的唯一依据。所以对组件的进行约束是创建一个健康组件的必要条件。这里我们约束属性类型为。使用方式运行结果没有错误假如我们再加入一个子组件控制台如预期报错自定义约束万物皆有其局限性。 日常扯淡前的废话 上一篇我们介绍了React中State对象,说到它是组件渲染的唯一依据;当然我们也可以认为State是组件中的数据源之一,它保存着组件渲染的所有数据并且可以直接作...

    kumfo 评论0 收藏0
  • [ 一起React系列 -- 7 ] 秘术之时间旅行-2

    摘要:但这样做的缺点很多,不利于状态在组件之间共享。所以本篇使用作为状态管理器来实现时间旅行。并且从中可以看出过程不仅仅向对象中添加一个状态对象,还对进行了加一操作,这是为了保证状态与保持同步。 距离上一次更新已经有半个月了,这半个月来主要在忙两件事:一个是最近老板给了个自动化测试任务,另一个是和学校的弟弟一起搞一个微信小游戏...emmmm!其实主要是懒!!! 本篇是作为上篇的续集,不知道...

    nidaye 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<