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

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

Form

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

class FormDownload extends Component {
    render() {
        return (
            <form method="get" action="http(s)://下载文件的后台接口">
                <button type="submit">Download!</button>
            </form>
        )
    }
}

export default FormDownload;

只要这一小段代码就能够实现文件的下载,是否是很开森?ios

Fetch

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

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 (
            <input type="button" value="下载" onClick={this.download}/>
        )
    }
}

export default FetchDownload;

麻烦在哪儿:express

一、须要考虑跨域问题
二、须要对返回值进行转化
三、须要有DOM操做(生成a标签和销毁a标签)

下面就一块儿来看看具体操做步骤:segmentfault

  1. 用fetch访问后台接口并接受后台返回值。由于fetch方法返回一个Promise对象,所以咱们能够在then用获取到它的返回值
  2. 这一步就厉害了。fetch的返回值是一个有意思的对象,它包含了不少方法,其中一个方法就是blob()。这个方法能够将fetch的返回值转化成Blob对象。
  3. 利用document.createElement建立一个a标签
  4. 利用window.URL.createObjectURL将blob数据转成对应url
  5. 经过fetch的响应头获取到文件名res.headers.get('Content-Disposition')。这里须要mark下,由于咱们后台使用了Cors中间件来解决跨域问题,所以须要作特别的设置来让Cors将响应头给暴露出来'exposedHeaders': '*',具体的你们能够看后台代码。
  6. 接下来就是对a标签的一系列操做,而后模拟点击事件触发下载动做。
  7. 最后须要将转化出来的url进行销毁window.URL.revokeObjectURL(url),a标签置为null

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

总结

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

相关文章
相关标签/搜索