M3U8 / HLS 的 CORS 跨域問題
「瀏覽器直接開網址可以,放進播放器就報錯」——這是 HLS 開發最常見的困惑之一。原因不在你的程式,而在瀏覽器的同源政策。
為什麼會發生 CORS 錯誤?
瀏覽器有一條安全規則叫同源政策(Same-Origin Policy):網頁上的 JavaScript 只能自由讀取「同源」的資源。https://mysite.com 想讀 https://cdn.other.com/stream.m3u8,就屬於跨來源請求。
此時瀏覽器會送出請求,但會檢查回應中有沒有:
Access-Control-Allow-Origin: *若沒有這個標頭(或允許的不是你的網域),瀏覽器就會擋下回應內容,控制台出現 CORS 錯誤,即使伺服器其實「已經把資料送出來了」。
簡單請求與預檢請求
CORS 分兩種情況,處理方式不同:
| 類型 | 觸發條件 | 行為 |
|---|---|---|
| 簡單請求 | GET、無自訂標頭 | 直接送出,檢查回應標頭 |
| 預檢請求 | 帶自訂標頭、非簡單方法 | 先送 OPTIONS 確認,通過才送真正的請求 |
所以如果你在請求中加了自訂標頭(例如某些授權標頭),來源端必須同時處理 OPTIONS,否則一樣會失敗。
可行的處理方向
- 自己架代理伺服器(最正規)
由你的後端去抓串流,再回傳給前端。這樣對瀏覽器而言是同源請求,並可在伺服器端加上必要的標頭。這是唯一在正式環境可靠的做法。 - 請來源端開放 CORS
如果你是內容擁有者,在 CDN 或伺服器設定中加入Access-Control-Allow-Origin即可。 - 改用原生播放
Safari 與部分行動瀏覽器支援原生 HLS 播放(<video> 直接吃 .m3u8),不受 JavaScript 的 CORS 限制。本站播放器會優先嘗試這個路徑。
常見問題
為什麼 M3U8 網址在瀏覽器直接開沒問題,用播放器卻 CORS 錯誤?
直接在網址列開啟屬於「導航請求」,不受同源政策限制。但播放器是用 JavaScript 的 fetch 或 XHR 取得檔案,會被同源政策檢查,只有來源伺服器回傳 Access-Control-Allow-Origin 標頭才能讀取。
這是我的程式寫錯嗎?
多數情況不是。CORS 是否放行完全由「來源伺服器」決定,前端無法繞過。你能做的是改用伺服器端代理,或請來源端加上對應標頭。
有辦法在前端直接繞過 CORS 嗎?
沒有正規做法。任何聲稱能繞過的技巧(如關閉瀏覽器安全設定)都不該用在正式環境,且會影響使用者安全。正確做法是架設自己的代理伺服器。
本站工具如何處理 CORS?
我們直接嘗試請求並誠實回報結果。若來源未開放 CORS,會明確顯示「來源未允許跨域存取」,而不是假裝成功。這也是本站與部分工具網站最大的差別。