跨域彻底讲透

发布于:2025-09-07 ⋅ 阅读:(23) ⋅ 点赞:(0)

跨域彻底讲透。


一、 跨域的定义

跨域指的是:当一个 Web 应用(位于一个域名下)试图去请求另一个域名下的资源时,如果这两个域名的协议、域名、端口有任何一项不相同,浏览器就会认为这是跨源的,并默认禁止这种请求。

浏览器的同源策略

同源策略是浏览器的一个最核心、最基础的安全功能。它规定:只有当协议、域名、端口三者完全相同时,才被认为是“同源”的,否则就是“跨域”或“跨源”。

  • 跨源例子
    • https://www.example.comhttp://www.example.com协议不同,HTTP vs HTTPS)
    • https://www.example.comhttps://api.example.com域名不同,主域 vs 子域)
    • https://www.example.comhttps://www.example.com:8080端口不同,443 vs 8080)

当发生跨域时,浏览器会拦截 Ajax 请求: 使用 XMLHttpRequestFetch API 发起的请求。


二、为什么?—— 为什么要存在跨域限制?

这是一个“浏览器多管闲事”的行为吗?绝对不是。这是为了安全

假设没有同源策略,会非常可怕:

  1. 你登录了银行网站(https://my-bank.com,浏览器保存了你的 Cookie 会话。
  2. 你无意中访问了一个恶意网站(https://evil-site.com
  3. 这个恶意网站上的脚本,可以用你的身份悄悄向 https://my-bank.com/transfer?to=hacker&amount=1000000 发起 AJAX 请求。
  4. 因为你的浏览器带着 my-bank.com 的 Cookie,银行服务器会认为这是你的合法操作,从而执行转账。

这就是可怕的 CSRF(跨站请求伪造) 攻击。同源策略极大地增加了这种攻击的难度

总结:同源策略的目的是为了保护用户信息安全和隐私,防止恶意网站窃取数据或冒充用户身份。


三、解决跨域的常见方案

既然跨域是浏览器搞的鬼,那我们的解决方案就是 “想办法让浏览器点头放行”

以下是主流且高效的解决方案,从上到下推荐程度递减:

方案一:(跨域资源共享)—— 官方终极方案

这是 W3C 标准,也是现代浏览器最推荐、最主流的跨域解决方案。它需要服务器和浏览器共同配合

原理:服务器 在响应头中设置一些特定的字段(如 Access-Control-Allow-Origin),告诉浏览器:“某个外域的请求是被我允许的,你别拦着”。

一个最简单的 CORS 请求:

  1. 前端代码(http://localhost:8080)正常发起一个 Fetch 请求到 http://api.example.com

  2. 服务器(api.example.com)在响应头中添加:

    Access-Control-Allow-Origin: http://localhost:8080
    # 或者允许所有域名(慎用)
    # Access-Control-Allow-Origin: *
    
  3. 浏览器看到这个响应头,比对请求的源(http://localhost:8080)和 Allow-Origin 的值,匹配成功,就会放行,让前端收到响应。

如何实现主要在服务器端配置。无论是 Node.js (Express)、Java (Spring)、Python (Django/Flask)、Nginx,都可以轻松设置 CORS 响应头。

方案二:反向代理 —— 开发阶段最常用方案

在开发和调试阶段,前端和后端 API 通常在不同端口(如前端 localhost:3000,后端 localhost:8080),这也会跨域。

原理“骗过”浏览器。我们让前端不是直接请求后端的地址,而是请求一个和自己同源的代理服务器(比如就是本地开发服务器)。由这个代理服务器偷偷地去请求真正的后端API,拿到结果后再转发给前端。因为服务器之间通信没有同源策略限制,所以没问题。

实现

  • Webpack DevServer / Vite: 在 vite.config.jswebpack.config.js 中配置 proxy

    // vite.config.js
    export default defineConfig({
      server: {
        proxy: {
          '/api': {
            target: 'http://localhost:8080', // 后端API地址
            changeOrigin: true,
            rewrite: (path) => path.replace(/^\/api/, ''),
          }
        }
      }
    })
    
  • Nginx: 在生产环境,也常用 Nginx 作为反向代理来处理跨域和负载均衡。


网站公告

今日签到

点亮在社区的每一天
去签到