networking

發佈

application/octet-stream 全解析:避免檔案被標為未知二進位 MIME Type

application/octet-stream 全解析:避免檔案被標為未知二進位 MIME Type
Photo by Jachan DeVol / Unsplash

深入解析 application/octet-stream MIME 類型:搞懂瀏覽器為何強制下載檔案、Content-Type 與 Content-Disposition 的正確用法,避免未知二進位資料拖垮使用者體驗

參考資料:
application/octet-stream @ mimetype.io

学习笔记:application/octet-stream @ Koshkaaa

Do I need Content-Type: application/octet-stream for file download? @ stackoverflow

為什麼 S3(或任何物件儲存服務)默默幫我改成 application/octet-stream
因為你上傳時沒有指定 Content-Type,AWS 為了不出錯,只好貼上萬用標籤 application/octet-stream。在 RFC 2046 - 4.5.1 裡,它被定義為 任意二進位資料,等同「先收著,之後再說」

application/octet-stream = 不知道你是誰,只知道你是 0 與 1 的集合

瀏覽器見到這張標籤怎麼辦?

  1. 先禮貌地放下滑鼠,開啟下載視窗
  2. 絕不嘗試解析、執行或顯示內容

這個預設行為是瀏覽器的安全機制:避免一個惡意可執行檔被偷偷跑起來,降低 XSS / RCE 風險

想像瀏覽器就是保全大叔:不認識的人先請登記

當 HTTP header 中的 Content-Type 設置為 application/octet-stream 時,瀏覽器的默認行為是觸發下載過程,而不是嘗試解析或執行文件。這種行為對於保護用戶安全非常重要,因為它防止了潛在的危險執行檔自動運行,進而降低了網絡安全風險

你在哪些場景看過它?

  • 電子郵件附件 : 當信件系統搞不清檔案類型時,就丟給收件人自己決定
  • 不明檔案下載 : 後端沒設定 MIME type,瀏覽器只好顯示「下載或取消」
  • API 傳檔 : 某些 REST/GraphQL API 直接回傳 binary stream,前端拿到後再用 blob 處理

Content-Disposition:給瀏覽器的小抄

📜 RFC 2616—HTTP/1.1 標準在 §19.5.1 節補充說明:Content-Disposition 並非核心 header,但實務上廣泛支援。它允許伺服器明確告訴瀏覽器「inline=能顯示就直接嵌入」「attachment=一定下載」,並建議加上 filename="..." 提供預設檔名

你可以在回應 header 裡再加一張小紙條 Content-Disposition,直接告訴瀏覽器:這份檔案要 inline 還是 attachment

Content-Type: application/octet-stream
Content-Disposition: attachment; filename="picture.png"
意味著:"我不知道這是什麼。請將其保存為文件,最好命名為 picture.png"
Content-Type: image/png
Content-Disposition: attachment; filename="picture.png"
意味著:"這是一個 PNG 圖片。請將其保存為文件,最好命名為 picture.png"
Content-Type: image/png
Content-Disposition: inline; filename="picture.png"
意味著:"這是一個 PNG 圖片。請顯示它,除非你不知道如何顯示 PNG 圖片。否則,或如果用戶選擇保存它,我們建議使用 picture.png 作為文件的名稱"

我該怎麼正確設定 MIME type?

  1. 後端固定值: 範例 (Node.js)
res.setHeader('Content-Type', 'image/png');
  1. S3 上傳時帶 ContentType — 範例 (AWS SDK v3):
await s3.send(new PutObjectCommand({
  Bucket: 'my-bucket',
  Key: 'cat.png',
  Body: fileBuffer,
  ContentType: 'image/png',
}));
  1. Nginx/Apache 自動偵測 — 啟用 mime.types 或對應模組

小結

  1. 沒貼標籤 → 瀏覽器把它直接搬回本機:application/octet-stream
  2. 想讓檔案正確顯示 → 上傳時貼好正確 Content-Type
  3. 要內用還外帶? → 用 Content-Disposition: inline(能顯示就嵌入)或 attachment(一定下載)

下次遇到一點開東西就下載,先檢查有沒有設定好 Content-Type,能省掉80% 問WTF的時間