application/octet-stream 全解析:避免檔案被標為未知二進位 MIME Type
深入解析 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 的集合
瀏覽器見到這張標籤怎麼辦?
- 先禮貌地放下滑鼠,開啟下載視窗
- 絕不嘗試解析、執行或顯示內容
這個預設行為是瀏覽器的安全機制:避免一個惡意可執行檔被偷偷跑起來,降低 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?
- 後端固定值: 範例 (Node.js)
res.setHeader('Content-Type', 'image/png');
- S3 上傳時帶
ContentType
— 範例 (AWS SDK v3):
await s3.send(new PutObjectCommand({
Bucket: 'my-bucket',
Key: 'cat.png',
Body: fileBuffer,
ContentType: 'image/png',
}));
- Nginx/Apache 自動偵測 — 啟用
mime.types
或對應模組
小結
- 沒貼標籤 → 瀏覽器把它直接搬回本機:
application/octet-stream
- 想讓檔案正確顯示 → 上傳時貼好正確
Content-Type
- 要內用還外帶? → 用
Content-Disposition: inline
(能顯示就嵌入)或attachment
(一定下載)
下次遇到一點開東西就下載,先檢查有沒有設定好 Content-Type,能省掉80% 問WTF的時間
Comments ()