<em id="wxnzf"></em>

    <noscript id="wxnzf"></noscript>
<wbr id="wxnzf"></wbr>

<tr id="wxnzf"><output id="wxnzf"></output></tr>
  • <wbr id="wxnzf"><legend id="wxnzf"></legend></wbr>

    <em id="wxnzf"><span id="wxnzf"></span></em>

  • <nav id="wxnzf"></nav>
    icon

    新聞 資訊

    News and information

    前端Javascript下載文件

    發布時間:2021-01-25

    項目開發中經常會有導出數據到Excel類似的需求,或者是下載文檔的需求。最簡單的下載方式是直接請求服務端文件地址,通過瀏覽器http實現文件下載。但是開發中,由于項目需求,你要下載的文件地址不會暴露給用戶,而且需要鑒權才允許下載文件,這個時候我們該怎么處理呢?


    應用場景

    文件地址沒有暴露在公網,無法通過文件url直接下載文件。


    要下載的文件內容可能是根據用戶請求動態生成的,如導出Excel數據表。


    后端需要鑒權驗證用戶提交的下載請求。


    實現流程

    前端發送get/post請求,攜帶header信息(如token用于鑒權),后端接收請求,完成鑒權后,讀取對應的文件,將文件以文件流的形式發送給瀏覽器,瀏覽器完成下載。


    我們把這種方式叫做Blob方式下載。


    Blob 對象表示一個不可變、原始數據的類文件對象。Blob 表示的不一定是JavaScript原生格式的數據。


    前端代碼

    我們以下載圖片為例,使用axios來做前端異步下載請求。


    get方式請求中,我們要在header中攜帶token信息,這個token就是你在系統中的通行證,一般是你在登錄的時候后端給你的token,相當于一張游樂場的門票,有了這張門票,你可以到游樂場里游玩任意項目,只是在游玩時給工作人員出示這個token門票就可以了。


    并且還要告訴后端,需要后端返回blob類型的數據,使用responseType: 'blob'。


    axios.get('http://localhost:9998/download.php', {

    headers: {

    'token': '1234512345'

    },

    responseType: 'blob'

    }).then((res) => {

    if (res.data.type !== 'application/octet-stream') {

    alert('下載失敗');

    return false;

    }


    const blob = new Blob([res.data], {

    type: 'image/jpeg'

    })


    let a = document.createElement("a");

    let objUrl = URL.createObjectURL(blob);

    a.href = objUrl;

    a.download = 'abc.jpg' //文件名

    a.click();

    URL.revokeObjectURL(objUrl); // 釋放內存

    document.body.removeChild(a);

    alert('下載成功');

    }).catch((err) => {

    console.log(err);

    alert('下載失敗');

    });

    我們拿到后端返回的blob對象數據后,在頁面上創建一個a標簽,然后模擬點擊事件,將blob數據保存成文件。注意URL.createObjectURL(blob)將blob保存在內存中,下載完后記得釋放內存哦。


    后端代碼

    在后端download.php中,先要在header中允許接收token,如果是跨域請求那就應該還要設置header("Access-Control-Allow-Origin: *");允許跨域請求。


    header("Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With, token");


    $token = isset($_SERVER['HTTP_TOKEN']) ? $_SERVER['HTTP_TOKEN'] : '';

    if ($token != '1234512345') {

    echo 'error.';

    exit;

    }


    $file = '../file/cc.jpg';

    if (!file_exists($file)) {

    header('HTTP/1.1 404 Not Found');

    exit;

    }


    $fileSize = filesize($file); 

    //下載文件需要用到的頭 

    header("Content-type: application/octet-stream"); 

    header("Accept-Ranges: bytes"); 

    header("Accept-Length:".$fileSize);

    $fp = fopen($file, "rb"); 

    $buffer = 1024; 

    $fileCount = 0; 

    //向瀏覽器發送數據 

    while(!feof($fp) && $fileCount < $fileSize){ 

        $cont = fread($fp, $buffer); 

        $fileCount += $buffer; 

        echo $cont; 

    }

    fclose($fp);

    接著就是驗證token是否正確,上述代碼中的驗證過程是偽代碼,實際開發中應該根據業務需求,按照一定的算法驗證token。token里面可能含有用戶信息和過期時間等數據。


    然后判斷要下載的文件是否存在,這個文件可能不在web目錄下,用戶無法直接通過url訪問。


    最后就是讀取文件流,發送給瀏覽器。


    亚洲 欧美 日韩 国产 在线,中文字幕乱码免费,很黄很刺激的免费视频,中日高清字幕版在线观看