前端必看:一口气搞懂跨域是什么、为什么、怎么解决

0 阅读3分钟

一、前言

做前端开发,跨域绝对是绕不开的问题。本地开发、联调后端、部署上线、面试,几乎处处都会遇到:

  • 控制台报错:No 'Access-Control-Allow-Origin'...
  • 请求发出去了,浏览器就是拿不到数据
  • 面试官一问跨域,只能说出 CORS

这篇文章从原理 → 为什么会跨域 → 所有解决方案,从零到一讲明白,看完彻底吃透跨域。

二、什么是跨域?

先记住一句话:跨域,是浏览器的安全策略限制,不是后端限制,也不是网络限制。

1. 同源策略(Same-Origin Policy)

浏览器为了安全,规定:只有协议、域名、端口完全一致,才叫「同源」,否则就是跨域。

对比一下:

当前页面:http://www.test.com:8080/index.html

请求地址是否跨域原因
http://www.test.com:8080/api不跨域完全一样
https://www.test.com:8080/api跨域协议不同(http/https)
http://api.test.com:8080/api跨域域名不同
http://www.test.com:9090/api跨域端口不同

只要有一个不一样,浏览器就会拦截响应,报跨域错误。

2. 关键点

  • 跨域请求能发出去,后端也能收到并返回
  • 浏览器拦截了响应,不给前端用
  • 服务器之间不存在跨域(只有浏览器有)

三、跨域解决方案(最全、最实用)

我按实际工作使用频率从高到低讲,你工作 99% 只用前 4 个。

1. CORS(最常用、最简单)

CORS:跨域资源共享,后端一行配置搞定

后端在响应头加:

Access-Control-Allow-Origin: *

或者指定域名:

Access-Control-Allow-Origin: http://localhost:8080

简单请求(GET/POST,无自定义头)直接生效。复杂请求(PUT/DELETE/ 自定义头)会先发 OPTIONS 预检请求

优点:标准、安全、推荐缺点:需要后端配合

2. 开发环境代理(webpack/vite 代理)

本地开发最常用,前端自己解决,不用找后端

vite 示例

// vite.config.js
export default {
  server: {
    proxy: {
      '/api': {
        target: 'http://localhost:3000',
        changeOrigin: true,
        rewrite: path => path.replace(/^/api/, '')
      }
    }
  }
}

原理:本地起个 Node 服务转发请求,服务器之间没有跨域

3. Nginx 反向代理(上线必备)

线上环境一般用 Nginx 转发,伪装成同源。

server {
  listen 80;
  server_name localhost;

  location /api {
    proxy_pass http://localhost:3000;
    proxy_set_header Host $host;
  }
}

前端请求 /api/xxx → Nginx → 真实接口。

4. JSONP(老方案,只支持 GET)

利用 <script src="xxx"> 不受跨域限制。

function cb(data) {
  console.log(data)
}

<script src="http://xxx/api?callback=cb"></script>

后端返回:

cb({ name: "test" })

缺点:只支持 GET,不安全,现在基本不用。

5. postMessage(iframe 跨域)

页面与 iframe、多窗口之间跨域通信。

// 父页面
iframe.contentWindow.postMessage('数据', '*')

// 子页面
window.addEventListener('message', e => {
  console.log(e.data)
})

6. WebSocket

WebSocket 不受同源策略限制,可以跨域通信。

7. document.domain、window.name

多用于同主域名不同子域名,现在很少用,了解即可。

四、方案怎么选?(直接照抄)

给你一个工作直接用的选择指南:

  1. 本地开发:webpack /vite 代理(首选)
  2. 生产环境:Nginx 代理 或 CORS
  3. 和后端配合:优先 CORS(标准方案)
  4. 老系统兼容:JSONP
  5. iframe 通信:postMessage

五、面试常问(背会直接用)

  1. 什么是跨域?为什么会有跨域?
  2. 跨域是浏览器限制还是服务端限制?
  3. CORS 简单请求和复杂请求区别?
  4. OPTIONS 请求是什么?
  5. 本地开发怎么解决跨域?
  6. JSONP 原理和缺点?

把这篇文章看完,这些问题全能答出来。

六、总结

  • 跨域 = 浏览器同源策略限制
  • 请求能发,响应被浏览器拦了
  • 工作常用:CORS、开发代理、Nginx 代理
  • 面试必考:原理 + CORS + 方案对比