首頁
學習紀錄
遊戲心得影視Life書單案件檔案
Side Projects委託作品與二創互動實驗場
Kurau
百百 BLOG
首頁
學習紀錄
遊戲心得影視Life書單案件檔案
Side Projects委託作品與二創互動實驗場
Kurau

Kurau Blog

「隨心而寫,真真假假,都是我」

一個記錄生活、輸出興趣的個人空間。
遊戲、影視、閱讀、學習……每一段體驗都值得留下文字。

頁面導覽

  • 學習紀錄
  • 遊戲心得
  • 影視Life
  • 書單
  • 委託作品與二創
  • Kurau
  • 合作邀請

找到我

歡迎來 Discord 找我聊天!

“曾經發生的事不可能忘記,只是暫時想不起來而已。”-《神隱少女》

© 2026 Kurau All rights reserved

後端與資料庫

CORS firebase

By Kurau·2023-04-17·Updated 2026-05-09·4 分鐘閱讀

Firebase Cloud Storage CORS 設定

TL;DR
Firebase Storage 跨域下載檔案會被 CORS 擋(出現 Access-Control-Allow-Origin 錯誤)。解法是 透過 gsutil cors set cors.json gs://<bucket> 設定 bucket 的 CORS policy,Firebase 控制台沒有 GUI 能改這個。

錯誤訊息

Access to fetch at 'https://firebasestorage.googleapis.com/v0/b/.../o/...'
from origin 'http://localhost:3000' has been blocked by CORS policy:
No 'Access-Control-Allow-Origin' header is present on the requested resource.

這個錯出現在:

  • 用 fetch() / XHR 想直接下載 Firebase Storage 上的檔案
  • 想把圖片轉成 Blob、Base64 或 Canvas 處理
  • 跨域 存取(讀取)檔案內容(直接 <img src> 顯示不會踩,因為瀏覽器走另一條路)

為什麼會被擋

Firebase Storage 的 default bucket 沒設 CORS。瀏覽器發 cross-origin fetch 時,server 的 response 沒有 Access-Control-Allow-Origin header → 瀏覽器拒絕該請求。

為什麼 <img> 不會踩
<img> / <video> 等 tag-based 載入是 simple request,不走 CORS preflight,所以能正常顯示。但要把圖內容讀進 Canvas / 轉 Base64 就要 CORS,crossorigin="anonymous" + bucket CORS 設定都要。

解法步驟

1. 建立 cors.json

[
  {
    "origin": ["*"],
    "method": ["GET"],
    "maxAgeSeconds": 3600
  }
]
json
"origin": ["*"] 是允許所有網域
正式環境建議改成具體網域:
"origin": ["https://yourdomain.com", "https://staging.yourdomain.com", "http://localhost:3000"]
json

2. 安裝 gsutil(Google Cloud SDK)

# macOS / Linux
curl https://sdk.cloud.google.com | bash
# 或 brew install google-cloud-sdk

# Windows:下載 installer
# https://cloud.google.com/sdk/docs/install
bash

3. 認證 + 設定 CORS

# 一次性登入
gcloud auth login

# 設定 CORS
gsutil cors set cors.json gs://your-project-id.appspot.com
bash

bucket 名通常是 <project-id>.appspot.com 或 <project-id>.firebasestorage.app(2024+ 新建專案)。在 Firebase Console → Storage 看上方就能找到。

4. 驗證

gsutil cors get gs://your-project-id.appspot.com
bash

應該回傳你剛設的 JSON。CORS 設定即時生效,但 瀏覽器 cache 可能要 hard reload(Cmd+Shift+R / Ctrl+Shift+R) 才看得到效果。


CORS 完整欄位

[
  {
    "origin": ["https://example.com"],
    "method": ["GET", "POST", "DELETE"],
    "responseHeader": ["Content-Type", "Authorization"],
    "maxAgeSeconds": 3600
  }
]
json
欄位說明
origin允許的來源網域
method允許的 HTTP 方法
responseHeader允許 client 讀取的 response header
maxAgeSecondspreflight 結果 cache 時間(秒)
一個 cors.json 多個 rule
可以針對不同 origin 設不同 method:
[
  { "origin": ["https://prod.com"], "method": ["GET"] },
  { "origin": ["http://localhost:3000"], "method": ["GET", "POST"] }
]
json

替代:用 Firebase SDK

如果用 Firebase SDK 的 getDownloadURL + fetch,SDK 會幫你處理一些事,但 fetch(downloadURL) 仍會踩 CORS。最好還是設 bucket CORS。

import { getStorage, ref, getDownloadURL } from 'firebase/storage';

const storage = getStorage();
const fileRef = ref(storage, 'images/photo.jpg');
const url = await getDownloadURL(fileRef);

const response = await fetch(url);   // ⚠️ 仍需 CORS 允許
const blob = await response.blob();
typescript

額外:Cloud Storage 內 metadata 的 CORS 也要

下載連結內含 access token,token 過期就 401。如果你的應用會 cache 連結,記得處理 連結重新生成 的邏輯,否則重啟後讀舊連結會壞。

參考
  • Firebase Cloud Storage Web 官方文件
  • 影片教學:fix CORS error in firebase storage

目錄

    ◆ 相關文章

    • Firebase 驗證 儲存到useContext

      2026-05-09
    • Firebase 前端API 是安全的

      2026-05-09
    • Firebase 資料庫如何建立 與 上傳

      2026-05-09
    • 一開始就獲取Firebase storage初始值

      2026-05-09
    ← 上一篇Firebase 前端API 是安全的下一篇 →Excel密碼破解

    ◆ 關於作者

    Kurau

    個人寫作 / 創作的 SoT,記錄遊戲、影視、學習與生活。

    更多 Kurau 的文章