什麼是 CORS(Cross-Origin Resource Sharing)? 該怎麼解決跨來源請求問題?
前端開發常常會遇到「跨來源請求被阻擋」的錯誤訊息,比如:
Access to fetch at 'https://api.example.com/data' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present...
這就是著名的 CORS 問題。本篇文章將說明 CORS 是什麼、為什麼會發生,以及常見的解法。
CORS 是什麼?
CORS(Cross-Origin Resource Sharing,跨來源資源共享)是一種瀏覽器的安全機制,用來限制「不同網域」之間的請求。簡單來說,它防止了一個網站的 JavaScript 去隨意讀取另一個網站的資料。
什麼是「跨來源」?
只要以下任何一個不同,就會被視為「不同來源」:
區塊 | 範例 |
---|---|
協定 | http://example.com vs https://example.com |
網域 | api.example.com vs www.example.com |
Port | example.com:3000 vs example.com:8000 |
為什麼會出現 CORS 錯誤?
瀏覽器會阻擋從網頁腳本對其他來源發起的請求(例如使用 fetch
、axios
)。除非 伺服器端主動聲明允許該請求的來源,否則請求會被攔截。
範例情境
假設前端使用 React (http://localhost:3000
),想從後端 API (http://localhost:8000
) 取得資料:
fetch('http://localhost:8000/api/data')
這是跨來源請求,除非後端有設定 CORS header,否則會被瀏覽器擋下來。
解決 CORS 問題的方法
1. 修改後端設定
CORS 問題應由「伺服器端」解決。需要在伺服器回應中加上正確的 Access-Control-Allow-Origin
header。
範例:使用 Express
const express = require('express');
const cors = require('cors');
const app = express();
app.use(cors()); // 允許所有來源
// 或只允許特定來源
// app.use(cors({ origin: 'http://localhost:3000' }));
app.get('/api/data', (req, res) => {
res.json({ message: 'Hello from server!' });
});
app.listen(8000);
範例:使用 Django + django-cors-headers
pip install django-cors-headers
# settings.py
INSTALLED_APPS = [
...
'corsheaders',
]
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
...
]
# 允許所有網域
CORS_ALLOW_ALL_ORIGINS = True
# 或只允許特定網域
# CORS_ALLOWED_ORIGINS = [
# "http://localhost:3000",
# ]
2. 使用 Proxy 避開 CORS
開發時可使用前端代理轉發請求,例如 React:
// vite.config.js or package.json
proxy: {
'/api': {
target: 'http://localhost:8000',
changeOrigin: true,
},
}
這樣 fetch('/api/data')
實際會被代理成後端的請求,不會被視為跨來源。
3. 後端設定 Access-Control Headers
除了 Access-Control-Allow-Origin
,有時也需要加上這些 header:
Access-Control-Allow-Origin: http://localhost:3000
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Content-Type, Authorization
這些設定也必須在「預檢請求(Preflight Request)」中正確處理。
面試題目
「請說明什麼是 CORS(Cross-Origin Resource Sharing),以及如果遇到 CORS 問題該如何解決?」
回答範例:
CORS(Cross-Origin Resource Sharing) 是一種瀏覽器的安全機制,用來限制前端從不同來源(origin)去請求資源,避免惡意網站竊取資料。當前端的 JavaScript 嘗試向不同網域、協定或 port 發送請求時,如果伺服器沒有正確設定 CORS header,瀏覽器會阻擋這個請求。
常見錯誤:
例如使用 fetch 或 axios 向不同來源的 API 發送請求時,會看到類似錯誤:
Access to fetch at 'http://api.example.com' from origin 'http://localhost:3000' has been blocked by CORS policy
解決方式:
-
從伺服器端設定 CORS header(這是正確的做法):
-
設定
Access-Control-Allow-Origin
,明確允許某個前端網域。 -
可搭配套件,如:
- Node.js 可用
cors
middleware - Django 可用
django-cors-headers
- Node.js 可用
-
-
本地開發時使用 proxy 轉發請求,避開跨域問題(開發用):
- 例如 React 可以設定
vite.config.js
或webpack devServer proxy
- 例如 React 可以設定
總結
問題 | 解法 |
---|---|
跨來源請求被阻擋 | 在後端加上 CORS Header |
特定網域允許 | 設定 Access-Control-Allow-Origin 為指定來源 |
多來源需求 | 使用動態設定或 whitelist |
本地開發測試 | 使用 Proxy 或開啟允許全部來源 |
延伸閱讀
如果曾經在開發中遇過 CORS 錯誤,不妨回頭看看是不是跨來源造成的限制,並從伺服器端著手解決吧!