1. 什么是跨域?

跨域(Cross-Origin)是指瀏覽器出于安全考慮,限制不同源(協議、域名、端口)之間的資源交互。
同源策略(Same-Origin Policy) 要求以下三者必須一致:
2. 跨域的表現形式
當以下場景發生在不同源時,瀏覽器會攔截請求:
3. 常見跨域解決方案
3.1 CORS(跨域資源共享)
原理:服務端通過響應頭聲明允許的跨域請求來源。
實現步驟:
1.簡單請求(GET/POST/HEAD,Content-Type 為 text/plain
、multipart/form-data
、application/x-www-form-urlencoded
):
服務端返回 Access-Control-Allow-Origin: *
或具體域名。
2.預檢請求(復雜請求如 PUT/DELETE 或自定義頭):
瀏覽器先發送 OPTIONS
請求,服務端需響應:
Access-Control-Allow-Origin: https://your-domain.com
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: Content-Type, Authorization
示例代碼(Node.js Express):
app.use((req, res, next) => {
res.header("Access-Control-Allow-Origin", "https://your-client.com");
res.header("Access-Control-Allow-Headers", "Content-Type, Authorization");
res.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
if (req.method === "OPTIONS") {
return res.sendStatus(200); // 快速返回預檢請求響應
}
next();
});
3.2 JSONP(JSON with Padding)
原理:利用 <script>
標簽無跨域限制的特性,通過回調函數獲取數據。
缺點:僅支持 GET 請求,存在安全風險(如 XSS)。
示例代碼:
// 前端
function handleResponse(data) {
console.log("Received:", data);
}
const script = document.createElement('script');
script.src = 'https://api.example.com/data?callback=handleResponse';
document.body.appendChild(script);
// 服務端返回
handleResponse({ "status": "success", "data": [...] });
3.3 代理服務器
原理:通過同源的后端服務轉發請求,繞過瀏覽器限制。
實現方式:
location /api/ {
proxy_pass https://api.example.com/;
proxy_set_header Host $host;
}
開發環境代理(如 webpack-dev-server)
// vue.config.js / webpack.config.js
module.exports = {
devServer: {
proxy: {
'/api': {
target: 'https://api.example.com',
changeOrigin: true,
}
}
}
};
3.4 WebSocket
原理:WebSocket 協議不受同源策略限制。
?示例代碼:
const socket = new WebSocket('wss://api.example.com/socket');
socket.onmessage = (event) => {
console.log('Message:', event.data);
};
3.5 其他方案
document.domain = "example.com";
postMessage API
用于窗口間通信(如 <iframe>
與父頁面):
// 發送方
window.parent.postMessage('Hello', 'https://parent-domain.com');
// 接收方
window.addEventListener('message', (event) => {
if (event.origin !== 'https://child-domain.com') return;
console.log('Received:', event.data);
});
4. 調試與注意事項
// 前端
fetch(url, { credentials: 'include' });
// 服務端
res.header("Access-Control-Allow-Credentials", "true");
res.header("Access-Control-Allow-Origin", "https://your-client.com"); // 不能為通配符 *
?
5. 總結
推薦方案:優先使用 CORS 或代理服務器。
兼容性場景:JSONP 適用于老舊系統。
實時通信:WebSocket 是理想選擇。
通過理解跨域機制及解決方案,開發者可靈活應對不同場景的跨域需求。
該文章在 2025/2/20 16:59:28 編輯過