Skip to content
 

跨域解决方式

更新: 11/20/2025字数: 0 字 时长: 0 分钟

一、什么是"跨域"?

当浏览器向 不同源(Origin) 的服务器发起请求时,就会触发跨域限制。判断"同源"需同时满足以下三项:

  1. 协议相同(HTTP/HTTPS)
  2. 域名相同(www.example.com)
  3. 端口相同(80/443)

以下均为跨域示例

  • http://a.comhttps://a.com(协议不同)
  • https://a.comhttps://api.a.com(子域名不同)
  • https://a.com:80https://a.com:8080(端口不同)

二、为什么浏览器要限制跨域?

1. 核心原因:安全防御

同源策略是为了防止恶意网站:

  • 窃取用户数据
    例:攻击者在页面嵌入脚本,偷偷访问用户的银行网站(假设用户已登录)。
  • CSRF 攻击
    利用用户 Cookie 伪造请求(如转账操作)。

2. 历史背景

  • 早期 Web 没有同源策略,导致 XSS/CSRF 攻击泛滥
  • 1995 年由 Netscape 浏览器首次引入,现成所有浏览器的标准

三、哪些操作会触发跨域限制?

1. 受同源策略限制的操作

操作类型示例是否跨域限制
AJAX 请求/Fetch 请求fetch('https://api.com/data')✅ 受限
Web 字体@font-face加载外部字体✅ 受限
Cookie/LocalStorage读取其他域的存储✅ 受限
drawImage()绘制其他域的图片✅ 受限
WebGL 贴图加载其他域的 3D 模型✅ 受限

2. 不受限的跨域资源

资源类型原因
<img>/<script>/<link>历史遗留,但要求服务端不返回敏感数据
跨域 CSS需确保Content-Type: text/css

四、跨域问题的技术本质

1. 浏览器的双重验证

当发起跨域请求时:

  1. 预检请求(Preflight)
    对复杂请求(如带自定义头的 POST),浏览器先发OPTIONS请求询问服务器是否允许跨域。

    http
    OPTIONS /data HTTP/1.1
    Origin: https://your-site.com
    Access-Control-Request-Method: POST
  2. 服务端响应 CORS 头
    服务器必须返回明确的许可头:

    http
    Access-Control-Allow-Origin: https://your-site.com
    Access-Control-Allow-Methods: POST, GET

2. 常见错误场景

  • 后端未配置 CORS 头:返回数据但被浏览器拦截
  • 证书不匹配:HTTPS 页面请求 HTTP 接口
  • 复杂请求未处理预检:如带Authorization头的 API

五、为什么移动端/Postman 没有跨域问题?

  • 浏览器是唯一执行者
    同源策略是浏览器行为,Postman/cURL/手机 App 直接发送 HTTP 请求,不受限制。
  • Native App 无同源策略
    安卓/iOS 应用可自由请求任意 API(但需自行处理安全问题)。

六、解决跨域的四种方式

6.1 JSONP(仅限 GET 请求)

原理:利用 <script> 标签不受同源策略限制的特性,通过动态创建脚本实现跨域请求。
特点

  • 仅支持 GET 请求。
  • 需要服务端配合返回回调函数包裹的数据(如 callback(data))。

示例代码

javascript
function jsonp(url, callbackName) {
  const script = document.createElement("script");
  script.src = `${url}?callback=${callbackName}`;
  document.body.appendChild(script);
  window[callbackName] = (data) => {
    console.log(data);
    document.body.removeChild(script);
  };
}
jsonp("http://api.example.com/data", "handleData");

适用场景:老旧浏览器兼容、简单数据获取。

6.2 前端代理(开发环境常用)

原理:在开发环境中,前端服务器(如 Vite/Webpack)代理请求到后端,绕过浏览器同源限制。
特点

  • 仅用于开发环境。
  • 无需后端配合,前端配置即可。

配置示例(Vite)

js
// vite.config.js
export default {
  server: {
    proxy: {
      "/api": {
        target: "http://api.example.com",
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/api/, "")
      }
    }
  }
};

适用场景:本地开发调试。

6.3 后端配置 CORS(生产环境推荐)

原理:服务端通过设置响应头 Access-Control-Allow-Origin 允许指定域名的跨域请求。
关键响应头

http
Access-Control-Allow-Origin: *  // 允许所有域名(或指定域名)
Access-Control-Allow-Methods: GET,POST,PUT  // 允许的请求方法
Access-Control-Allow-Headers: Content-Type  // 允许的请求头
Access-Control-Allow-Credentials: true  // 允许携带Cookie(需前端配合)

后端示例(Node.js)

js
res.setHeader("Access-Control-Allow-Origin", "https://your-frontend.com");
res.setHeader("Access-Control-Allow-Methods", "GET,POST");

适用场景:生产环境跨域请求。

6.4 Nginx 反向代理(生产环境高效方案)

原理:通过 Nginx 配置反向代理,将跨域请求转发到目标服务器,并添加 CORS 头。
配置示例

nginx
server {
  listen 80;
  server_name your-frontend.com;

  location /api {
    proxy_pass http://api.example.com;
    add_header 'Access-Control-Allow-Origin' 'https://your-frontend.com';
    add_header 'Access-Control-Allow-Methods' 'GET,POST';
    add_header 'Access-Control-Allow-Headers' 'Content-Type';
  }
}

优势

  • 高性能,无需修改后端代码。
  • 可统一管理跨域策略。

适用场景:生产环境多服务跨域。

6.5 对比总结

方案适用场景请求类型是否需要后端配合安全性
JSONP老旧项目兼容GET
前端代理开发环境所有
后端 CORS生产环境所有
Nginx 代理生产环境所有否(运维配置)

我见青山多妩媚,料青山见我应如是。