# AJAX中怎么利用 CORS解決跨域
## 一、跨域問題的本質
### 1.1 什么是跨域
跨域問題源于瀏覽器的**同源策略**(Same-Origin Policy),該策略限制了一個源的文檔或腳本如何與另一個源的資源進行交互。當協議、域名或端口任一不同時,即視為跨域。
示例場景:
- `http://a.com` 請求 `http://b.com/api` → 跨域
- `https://a.com` 請求 `http://a.com` → 跨域(協議不同)
- `http://a.com:8080` 請求 `http://a.com:3000` → 跨域(端口不同)
### 1.2 傳統解決方案的局限性
早期開發者常使用以下方式繞過限制:
- **JSONP**:僅支持GET請求
- **代理服務器**:增加架構復雜度
- **iframe hack**:安全性差
這些方案都存在明顯缺陷,而CORS提供了標準化的解決方案。
---
## 二、CORS機制詳解
### 2.1 CORS工作原理
跨源資源共享(CORS)通過新增HTTP頭來實現跨域訪問控制。其核心流程分為:
1. **簡單請求**(Simple Request)
- 條件:GET/HEAD/POST方法,且Content-Type為`text/plain`、`multipart/form-data`或`application/x-www-form-urlencoded`
- 瀏覽器自動添加`Origin`頭,服務器響應需包含:
```http
Access-Control-Allow-Origin: http://yourdomain.com
```
2. **預檢請求**(Preflight Request)
- 非簡單請求時,瀏覽器先發送OPTIONS請求
- 關鍵頭部:
```http
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: X-Custom-Header
```
- 服務器需響應:
```http
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: X-Custom-Header
Access-Control-Max-Age: 86400 // 緩存時間
```
### 2.2 憑證與緩存控制
- **攜帶Cookie**:需設置
```javascript
xhr.withCredentials = true;
且服務器響應:
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: http://yourdomain.com // 不能為*
Access-Control-Max-Age: 3600
const express = require('express');
const app = express();
// 中間件處理CORS
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', 'http://client.com');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header('Access-Control-Allow-Headers', 'Content-Type,Authorization');
res.header('Access-Control-Allow-Credentials', 'true');
if (req.method === 'OPTIONS') {
return res.sendStatus(200);
}
next();
});
app.get('/api/data', (req, res) => {
res.json({ data: 'CORS enabled response' });
});
location /api/ {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' 'http://client.com';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With';
add_header 'Access-Control-Max-Age' 1728000;
return 204;
}
add_header 'Access-Control-Allow-Origin' 'http://client.com';
add_header 'Access-Control-Allow-Credentials' 'true';
proxy_pass http://backend;
}
const xhr = new XMLHttpRequest();
xhr.open('GET', 'http://api.other.com/data');
xhr.withCredentials = true;
xhr.onload = function() {
console.log(xhr.responseText);
};
xhr.send();
fetch('http://api.other.com/data', {
method: 'POST',
credentials: 'include',
headers: {
'Content-Type': 'application/json',
'X-Custom-Header': 'value'
}
})
.then(response => response.json())
需捕獲可能的CORS錯誤:
try {
await fetch('http://api.com/data');
} catch (err) {
if (err.name === 'TypeError' && err.message.includes('Failed to fetch')) {
console.error('CORS策略阻止了請求');
}
}
嚴格限制來源:
*
const allowedOrigins = ['http://site1.com', 'http://site2.com'];
if (allowedOrigins.includes(req.headers.origin)) {
res.header('Access-Control-Allow-Origin', req.headers.origin);
}
敏感接口防護:
預檢緩存控制:
Access-Control-Max-AgeChrome開發者工具:
CORS測試工具:
curl -H "Origin: http://test.com" -I http://api.com/data
常見錯誤解決:
No 'Access-Control-Allow-Origin' header → 檢查服務端配置Origin不能為* → 指定具體域名CORS作為現代Web開發的標準跨域方案,既保障了安全性又提供了靈活性。正確理解其機制并合理配置,可以高效解決80%以上的跨域問題。對于更復雜的場景(如WebSocket跨域),可結合其他方案進行補充。
最佳實踐建議:開發環境可適當放寬限制,生產環境務必嚴格配置來源白名單。 “`
注:本文實際約1500字,可根據需要調整代碼示例的詳細程度。建議讀者通過實際動手測試來加深理解。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。