題幹與適用場景
你要在瀏覽器中上傳大檔案並計算摘要。新瀏覽器支援 Blob.bytes(),但舊瀏覽器可能不支援。請設計讀取、分片、回退、取消、錯誤處理與相容性驗證方案。
MDN 將 Blob.bytes() 標為 Baseline 2026:它回傳 Promise,最後得到包含 Blob 內容的 Uint8Array,也可在 Web Worker 使用。重點是 API 語意與資源邊界,不是把「支援新 API」當成完整上傳方案。
面試官考察點
- 能否準確說明
bytes()回傳 Promise 與Uint8Array,避免把它當成串流。 - 能否識別整個 Blob 讀取造成的記憶體峰值,並設計分片或串流路徑。
- 能否提供特性偵測與
arrayBuffer()、stream()等回退,而非按瀏覽器名稱判斷。 - 能否處理取消、重試、摘要狀態、Worker 通訊與使用者回饋。
- 能否用相容性矩陣與大檔案壓力測試證明方案可用。
需要先釐清的問題
- 檔案大小上限、並行上傳數、目標瀏覽器與是否支援 Web Worker 是什麼?
- 摘要演算法、服務端分片協定、斷點續傳與重複區塊去重如何定義?
- 上傳前必須得到完整摘要,還是可以邊讀邊上傳並最後校驗?
- 失敗後是否允許從已確認的區塊恢復,服務端如何保證冪等?
- 使用者切換頁面、關閉分頁或裝置記憶體緊張時,任務如何停止與恢復?
API 語意與讀取路徑
Blob.bytes() 不接收參數,回傳 Promise;成功值是 Uint8Array,失敗時 Promise reject。它會把 Blob 內容作為連續位元組陣列交給呼叫方,因此不能宣稱零拷貝或無限制處理大檔案。小檔案可在 Worker 讀取並計算摘要,大檔案應優先使用 slice() 切塊,再逐塊讀取與上傳。
先做能力偵測,再選路徑:支援時使用 bytes(),否則使用 arrayBuffer() 轉成 Uint8Array;若目標瀏覽器與協定允許,使用 stream() 逐塊消費。回退程式碼應維持相同的塊編號、摘要輸入與錯誤契約,不能因舊 API 改變服務端校驗。
記憶體、分片與摘要
把整份 Blob 讀入記憶體的峰值至少與檔案大小同量級,還要加上上傳緩衝、解碼與執行期開銷。按固定或自適應大小呼叫 slice(start, end),每次只保留目前區塊與有限的上傳佇列。摘要器要按順序接收區塊;並行上傳不能改變摘要輸入順序。
每個區塊帶檔案 ID、版本、區塊序號、長度與內容摘要。服務端以檔案 ID 加區塊序號冪等寫入,最後按順序合併並校驗總長度與整檔摘要。區塊摘要不能取代端到端摘要,因為遺失、重排或錯誤拼接仍可能形成錯誤檔案。
取消、重試與 Worker
使用 AbortController 把取消訊號傳給讀取與上傳請求;取消後清空待上傳佇列並釋放參照。重試只針對可恢復錯誤,使用指數退避與冪等區塊鍵;認證失效應暫停並重新授權,不應無限重試。Worker 負責摘要計算時,主執行緒只接收進度、錯誤與最終結果,避免把整個位元組陣列複製回主執行緒。
若採用 stream(),要遵守背壓,讀取器速度不能超過網路與摘要器處理能力。任何路徑都要記錄已確認區塊數、讀取耗時、上傳耗時、重試次數、取消原因與峰值記憶體估計,但日誌不得包含檔案內容或敏感路徑。
相容性與安全邊界
特性偵測應檢查 typeof Blob !== "undefined" 以及 "bytes" in Blob.prototype,再進入 bytes() 路徑。不要只根據 User-Agent 判斷。舊瀏覽器回退到 arrayBuffer() 或受控的 FileReader,並在不符合記憶體預算時明確提示使用者。
客戶端摘要只能用於完整性校驗,不能取代服務端授權、病毒掃描與內容類型驗證。服務端必須限制檔案大小、區塊大小、區塊序號範圍與總時長;客戶端傳來的 MIME 類型不可直接作為安全判斷。跨 Worker 傳輸時避免複製敏感內容,完成後儘快釋放參照。
失敗演練與驗證清單
覆蓋支援與不支援 bytes() 的瀏覽器、Web Worker 與主執行緒、空檔案、單區塊檔案、跨區塊檔案、超大檔案、網路中斷、取消後恢復、重複區塊、順序錯亂與摘要不匹配。壓力測試記錄 p95 讀取時間、上傳吞吐、峰值記憶體、長任務、失敗率與恢復時間。
若 bytes() reject,保留區塊狀態並切換到明確回退;若回退也超出記憶體預算,停止任務並說明下一步,而不是強行讀取整檔。若服務端發現區塊摘要或總摘要不匹配,丟棄未確認合併結果,允許從最後一致區塊恢復。
延伸追問與參考答案
bytes() 與 arrayBuffer() 應如何選擇?
兩者都可能把完整 Blob 內容讀入記憶體;bytes() 直接給出 Uint8Array,適合需要位元組視圖的程式碼,但不會自動取得串流處理能力。大檔案應優先分片或串流方案。
為什麼不能只做客戶端整檔摘要?
整檔摘要無法證明服務端按正確順序收到所有區塊,也不能取代授權與內容安全檢查。應同時驗證區塊序號、區塊摘要、總長度與服務端最終摘要。
如何驗證舊瀏覽器回退?
用能力偵測強制覆蓋支援與不支援路徑,配合真實瀏覽器矩陣、Worker/主執行緒、記憶體壓力、斷網恢復與取消測試;不能只在一台新瀏覽器驗證。