[ 一塊兒學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貼一下,有興趣的同窗能夠下載下來跑一下溜溜框架

相關文章
相關標籤/搜索