网络相关 - 跨域解决方式

文章目录

    • 一、什么是"跨域"?
    • 二、为什么浏览器要限制跨域?
      • [1. 核心原因:安全防御](#1. 核心原因:安全防御)
      • [**2. 历史背景**](#2. 历史背景)
    • 三、哪些操作会触发跨域限制?
      • [1. 受同源策略限制的操作](#1. 受同源策略限制的操作)
      • [2. 不受限的跨域资源](#2. 不受限的跨域资源)
    • 四、跨域问题的技术本质
      • [1. 浏览器的双重验证](#1. 浏览器的双重验证)
      • [2. 常见错误场景](#2. 常见错误场景)
    • [五、为什么移动端/Postman 没有跨域问题?](#五、为什么移动端/Postman 没有跨域问题?)
    • 六、解决跨域的四种方式
      • [6.1 JSONP(仅限 GET 请求)](#6.1 JSONP(仅限 GET 请求))
      • [6.2 前端代理(开发环境常用)](#6.2 前端代理(开发环境常用))
      • [6.3 后端配置 CORS(生产环境推荐)](#6.3 后端配置 CORS(生产环境推荐))
      • [6.4 Nginx 反向代理(生产环境高效方案)](#6.4 Nginx 反向代理(生产环境高效方案))
      • [6.5 对比总结](#6.5 对比总结)

一、什么是"跨域"?

当浏览器向 不同源(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请求询问服务器是否允许跨域。

    bash 复制代码
    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 允许指定域名的跨域请求。
关键响应头

bash 复制代码
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 头。
配置示例

bash 复制代码
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 代理 生产环境 所有 否(运维配置)

👉点击进入 我的网站

相关推荐
X54先生(人文科技)17 小时前
《元创力》纪实录·桥段薪火三纪
网络·人工智能·开源·ai写作·零知识证明
学不会pwn不改名17 小时前
【ArchLinux】如何制服国产免驱网卡
linux·运维·网络
宝宝宝阿18 小时前
前端访问后台接口存在跨域问题,如何处理解决
前端
广州华水科技18 小时前
北斗GNSS与单北斗变形监测在水库安全监测中的应用探索
前端
WIZnet18 小时前
MQTTS连接adafruit平台示例
网络·以太网·wiznet
蜡台18 小时前
使用 html javascript 实现 金币落袋效果
前端·javascript·html
凯瑟琳.奥古斯特18 小时前
UDP检验和原理详解
网络·网络协议
IT_陈寒18 小时前
为什么我的Python multiprocessing总是卡在join()?
前端·人工智能·后端
李白的天不白18 小时前
VUE依赖配置问题
前端·javascript·vue.js
m0_7381207218 小时前
后渗透维权提权基础——CTF模拟红队进行权限维持(二)
前端·网络·windows·python·安全·php