檔案上傳這件小事:從 KB 到 GB

檔案上傳這件小事:從 KB 到 GB

2026-01-29

從幾 KB 的頭像到幾 GB 的影片,背後的技術方案完全不同:斷點續傳、分片上傳、直傳 S3,什麼場景該用什麼方案?

「上傳檔案」這個需求,幾乎每個產品都會遇到:

  • 使用者要上傳圖片、大頭貼
  • 客戶上傳報表或 JSON
  • 管理後台支援多個影片素材、PDF、原始圖檔

乍看之下,好像就是表單加個 <input type="file" /> 的事

但真的做過你就知道,檔案上傳是一場關於 bit & byte 的戰爭

這篇來聊聊我自己在幾個專案裡踩過的坑,從小檔案的基本做法,到大檔案/斷線重傳場景的處理,再到常見的一個問題:檔案到底應不應該經過後端伺服器?

小檔案沒那麼複雜,但也不是免洗碗

先從最基本的說起:小檔案上傳流程,就是你平常最常看到的那種:

使用者選檔案 → 前端 form / fetch / axios 傳到後端 → 後端接收存檔

通常你會這樣做:

前端

  • <input type="file"> 拿到 File 物件
  • FormData.append("file", file) 包起來
  • axios.post("/upload", formData) 丟到後端

後端

  • 用 multer(Node.js)或其他 multipart parser
  • 存進硬碟、S3、或其他儲存服務

這一段有個關鍵詞:multipart/form-data

這是大多數瀏覽器傳檔案時的預設格式。

這樣的流程夠用嗎?對小圖、PDF、音訊都很 OK。

但你一遇到以下情況,就會開始痛:

  • 使用者上傳 2GB 的影片
  • 傳到一半網路斷了
  • 上傳過程沒有進度條
  • Server memory / timeout 壓力大

TUS:大檔案/斷網重傳場景的救星

第一次遇到上傳大檔的需求時,我們的反應是:「來切 chunk 吧」。

  • 檔案切成 N 段
  • 一段段傳
  • 成功再合併

這聽起來很合理,也有很多 DIY 的實作方式,

但後來我們選擇了一個標準協議:TUS (tus.io)

為什麼選 TUS?

TUS 是一個專門為「斷點續傳」與「大檔案上傳」而生的協議。它不是某個框架,而是一種設計約定,你可以在任何語言/環境下實作。

它的設計有幾個超實用的特點:

  • 支援斷線重傳
  • 上傳可中斷、恢復
  • 有進度 API
  • 可以支援多平台(前端、行動裝置、桌面)

TUS 流程概念圖:

sequenceDiagram
    participant Client
    participant TUSServer

    Client->>TUSServer: POST /files → 創建資源(取得 upload URL)
    loop 每段上傳
        Client->>TUSServer: PATCH /files/:id → 傳送 chunk
        TUSServer-->>Client: 204 No Content
    end
    Client->>TUSServer: HEAD /files/:id → 查詢進度(optional)

實作選項

  • 前端:官方有 JS SDK(tus-js-client)
  • 後端:Node.js 可用 tus-node-server,或用 nginx-tus module
  • 也可以選用第三方服務,例如 Uppy + tusd

TUS 解決了什麼?

  • 傳到一半斷線也不怕
  • 可以 resume,不必重傳整包
  • 可做進度條、暫停/繼續功能
  • Server 壓力小(不需要一次吃下整包檔案)

那檔案到底要不要經過自己的後端?

這是一個老問題,永遠沒有絕對答案。

你會看到兩種流派:

1. 檔案直接上傳到第三方儲存服務(例如 S3、Cloudflare R2)

流程是這樣:

  • 前端先 call 你的 API 拿預簽名 URL(presigned URL)
  • 使用者直接把檔案丟到該 URL
  • 上傳完再回報 metadata 給你的系統

這樣做的優點:

  • 不經過你後端,頻寬成本幾乎為 0
  • 後端不會被大檔打死
  • 更接近 serverless 架構的設計哲學

但缺點是:

  • 前端流程變複雜
  • 權限控管與驗證必須靠 URL 有效期/scope 控制
  • 檔案驗證(副檔名、大小、MIME)會轉移到前端做

2. 檔案先丟後端,再由後端存到儲存服務

這是比較「傳統、可控」的作法,尤其在以下情境特別實用:

  • 你需要即時分析/過濾檔案(例如掃毒、轉檔)
  • 需要寫 DB log 紀錄每次上傳內容
  • 想統一 log pipeline/錯誤處理機制

從 file input 到資料流設計,PM 能懂多少就差多少

做過檔案上傳的人都知道,這件事情從 UI 角度看真的不複雜

但一旦要處理大檔案、中斷重傳、後端壓力控制、CDN 邊界、權限驗證、資料入庫…

你會發現這根本不是單純「接個表單」的問題

以前當 PM 的時候我也會說:

「就給我一個上傳按鈕,檔案丟上去就好」

但現在回頭看,真的懂一點技術會讓你少問很多笨問題,也能早一點預判風險在哪:

  • 上傳會不會拖慢主流程?
  • 使用者上傳失敗怎麼辦?能不能續傳?
  • 檔案是要經過我們後端?還是直接傳到儲存服務?
  • 哪一段才是我們要負責控的責任邊界?

理解這些,才能跟工程師一起討論怎麼設計資料流,而不是停留在「上傳壞了你修一下」的層級

你不需要會寫 chunk uploader

但你需要知道,這不是單純在傳檔案,這是在管理風險與責任邊界