跨域(Cross-Origin)是指瀏覽器在執行 JavaScript 的時候,因為同源策略(Same-Origin Policy)的限制,阻止了一個網頁去請求不同源(域名、端口、協議有任意一個不同)的資源。
1. 什么是同源策略?
- 同源指:
- 協議(http / https)
- 域名(www.example.com / api.example.com)
- 端口(80 / 8080)
- 必須全部相同才算同源。
- 只要有一個不同,就算跨域。
例子:
當前頁面地址:http://www.a.com:8080
以下都是跨域:
1. http://www.b.com:8080 // 不同域名
2. https://www.a.com:8080 // 不同協議
3. http://www.a.com:8081 // 不同端口
2. 跨域是如何造成的?
- 跨域的根本原因是瀏覽器的安全限制。
- 瀏覽器為了防止惡意網站竊取數據,不允許前端腳本直接讀取其他源的響應數據。
注意:跨域限制只存在于瀏覽器端的 Ajax/Fetch 請求,后端請求(比如 Node.js 調用接口)是沒有跨域限制的。
3. 前端開發常見跨域解決方案
- 方案 1:CORS(最常用)
- 核心原理:后端在響應頭中加 Access-Control-Allow-Origin 等字段,告訴瀏覽器允許該域訪問。
示例:
Access-Control-Allow-Origin: http://www.a.com
Access-Control-Allow-Methods: GET,POST,PUT,DELETE
Access-Control-Allow-Headers: Content-Type
- 優點:標準、安全、靈活。
- 缺點:需要后端配合。
- 方案 2:JSONP(老舊方法,只支持 GET)
- 原理:利用 <script>標簽不受同源策略限制的特性,通過回調函數接收數據。
示例:
<script src="http://api.b.com/data?callback=handleData"></script>
<script>
function handleData(data) {console.log(data);
}
</script>
- 優點:簡單,不需要改瀏覽器。
- 缺點:只能 GET,請求安全性低,現在基本淘汰。
- 方案 3:反向代理(本地開發常用)
- 原理:在本地開發服務器(如 Webpack devServer、Vite、Nginx)配置代理,把請求轉發到后端,避開瀏覽器跨域限制。
示例(vite.config.js):
export default {server: {proxy: {'/api': {target: 'http://backend.com',changeOrigin: true,rewrite: path => path.replace(/^\/api/, '')}}}
}
示例(Nginx加 CORS 響應頭):
server {listen 80;server_name www.example.com;location /api/ {proxy_pass http://api.example.com/;# 添加 CORS 頭add_header Access-Control-Allow-Origin *;add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';add_header Access-Control-Allow-Headers 'Origin, Content-Type, Accept, Authorization';# 預檢請求(OPTIONS)直接返回if ($request_method = OPTIONS) {return 204;}}
}
- 注意:
- proxy_pass 后面是否有 / 很重要:
- proxy_pass http://api.example.com/; → /api/user → http://api.example.com/user
- proxy_pass http://api.example.com; → /api/user → http://api.example.com/api/user
- proxy_pass 后面是否有 / 很重要:
- 方案 4:PostMessage / iframe
- 原理:如果需要跨域頁面之間通信,可以用 window.postMessage。
- 用途:跨域 iframe、跨窗口通信。
- 方案 5:跨域資源共享(特殊標簽)
- <img>, <script>, <link> 天生可以跨域加載資源,但不能直接獲取內容(除非設置 CORS)。
- 方案 6:同源策略的“放寬”
- 修改瀏覽器配置(比如 Chrome 啟動參數 --disable-web-security),但只建議本地調試,生產不可用。