Stories

Detail Return Return

Chrome 下載大文件報錯!用 Streamsaver.js 完美填坑 - Stories Detail

本文系轉載,轉載鏈接:Chrome 下載大文件報錯!用 Streamsaver.js 完美填坑

前言

用 Chrome 下載大文件時,有時會彈出 “網絡錯誤”,換其他瀏覽器卻能正常下載。今天就來排查一下這個問題產生的原因,提供一些解決思路給大家。

一、為什麼 Chrome 獨有的 “大文件下載坑”?

同樣的網絡、同樣的文件,Chrome 報錯而其他瀏覽器正常,核心問題出在 Chrome 對 “大文件數據處理” 的特殊限制上:Chrome 處理大文件時,默認用Blob類型存儲數據,但Blob對大文件有隱性限流,一旦文件超過閾值,就會觸發 “網絡錯誤” 的保護機制;而其他瀏覽器對Blob的限制更寬鬆,所以能正常下載。

二、嘗試思路:把 responseType 從 Blob 換成 ArrayBuffer

如果下載的文件在 1-2G 之間,這個方法能快速解決問題,具體操作和原理如下:

1. 為什麼換 ArrayBuffer 有用?

Blob像 “固定大小的紙箱”,裝太大的東西會變形(觸發限流);而ArrayBuffer像 “可伸縮的布袋”,能更靈活地容納大文件數據,避開 Chrome 對Blob的限流機制。簡單來説,把請求響應的數據類型從Blob改成ArrayBuffer,就能讓 Chrome 正常處理 1-2G 的文件下載。

2. 注意:ArrayBuffer 不是 “萬能藥”

這個方法有明確的侷限:當文件超過 3G 時,ArrayBuffer會佔用大量內存,從而導致兩種問題出現 —— 要麼 Chrome 直接崩潰,要麼下載的文件變成幾 K / 幾 B 的殘缺文件,相當於 “布袋裝太多東西會撐破”。如果你的文件在 3G 以內,用這個方法能臨時救急;超過 3G,就需要更徹底的方案。

三、完美解決 —— 用 Streamsaver.js 實現流式下載,支持超大文件

經過多次嘗試,最終發現Streamsaver.js能徹底解決問題,它就像 “給大文件開了‘綠色通道’”,通過 “流式傳輸” 邊接收數據邊保存,不佔用大量內存,還能避開 Chrome 的各種限制。

1. 什麼是 “流式傳輸”?

傳統下載是 “先把整個文件收到瀏覽器裏,再保存到本地”,就像 “先把水裝滿桶,再倒進盆裏”,但是桶太小就會溢出;而流式傳輸是 “收到一點水就倒進盆裏”,不用等水裝滿桶,既能處理超大文件,又不佔用過多內存。

2. Streamsaver.js 的具體使用步驟

第一步:安裝依賴

在項目中執行命令安裝Streamsaver.js

npm i streamsaver

第二步:編寫下載函數

在代碼中引入工具並編寫下載邏輯:

import streamSaver from "streamsaver"

export async function streamSaverTest(url, name) {
    var url = baseURL + url
    const currentUrl = window.location.origin;
    StreamSaver.mitm = `${currentUrl}/mitm.html?version=2.0.0`
    const fileStream = StreamSaver.createWriteStream(`${name}.zip`);
    fetch(url, {
        method: 'GET',
        headers: { 'Authorization': 'Bearer ' + getToken() },
    }).then((res) => {
        console.log('=-res', res)
        const readableStream = res.body
        if (window.WritableStream && readableStream.pipeTo) {
            return readableStream.pipeTo(fileStream).then(() => console.log('下載完成'))
        }
    })
}

3. 為什麼不用 Axios,偏用 Fetch?

因為 Axios 的responseType只支持arraybufferblob等固定類型,不支持 “流(stream)”;而 Fetch 能直接獲取響應的body流數據,和Streamsaver.js的流式傳輸完美適配。

四、總結

在建設網站的過程中,面對 Chrome 大文件下載錯誤,通用 Streamsaver.js 做流式下載,一般情況都可以解決問題。

user avatar u_17470194 Avatar yejianfeixue Avatar silkide Avatar wayn111 Avatar xixu Avatar fengliudeshanghen Avatar
Favorites 6 users favorite the story!
Favorites

Add a new Comments

Some HTML is okay.