前端跨域解决方案(1):什么是跨域?

1 URL

URL(Uniform Resource Locator)是互联网上的一种资源的简洁标识。它是一种特定格式的字符串,可以指向互联网上的任何资源。当我们在浏览器中输入一个网址,它的结构其实暗含着多层信息。以http://username:password@www.example.com:80/path/to/file.html?key1=value1&key2=value2#section 为例,其各部分功能如下:

1.1 协议(Protocol)

如图中 http 的部分,定义数据传输的格式、加密方式、错误处理机制等,确保客户端和服务器能正确通信,常见的协议有:

  • **http:**Hypertext Transfer Protocol,超文本传输协议,不加密,明文传输,安全性较低(默认端口80)

  • **https:**HTTP Secure,安全超文本传输协议,加密传输(默认端口443),用于安全场景(如支付、登录等)

  • **ftp:**File Transfer Protocol,文件传输协议,用于文件服务器

  • **file:**用于访问本地文件系统的文件

1.2 认证信息(Credentials)

如图中 user:pass@ 的部分,用于需要身份验证的服务(如私有 FTP 服务器),浏览器通常自动隐藏该部分。

1.3 域名(Host Name)

如图中 site.com 的部分,这部分称为域名或主机名,它定义了我们想要访问的服务器的地址。这可以是一个IP地址(如 http://192.168.1.1)或者一个注册的域名(如 www.baidu.com)。

1.4 端口号(Port)

如图中 80 的部分,它定义了我们要访问服务器上的哪个服务。如果未指定,那么默认端口是协议的标准端口(例如,对于 HTTP 是 80,HTTPS 是 443,FTP 是 21)。

1.5 路径(Path)

如图中 /pa/th 的部分,它定义了服务器上资源的具体位置。

1.6 查询参数(Query Parameters)

如图中 ?q=val 的部分,用于向服务器传递参数,以 ? 开头,通过 key=value 的格式传递,多个参数用 & 分隔。

1.7 锚点(Hash)

如图中 #hash 的部分,以 # 开头,用于定位网页内的具体位置(如 #section1 会让浏览器滚动到页面中 id="section1" 的元素)。

2 什么是跨域?

"跨域"是指浏览器为了安全性,设置的同源策略限制。同源策略(Same-Origin Policy) 是浏览器的核心安全机制,它规定:只有协议、域名、端口完全相同的资源才属于同一源(Same Origin),否则视为跨域(Cross-Origin),跨域请求会被浏览器默认阻止。那为什么需要跨域限制呢?举个例子:

若没有同源策略,恶意网站 malicious.com 可通过 JS 脚本执行以下操作:

  1. 在页面中嵌入 http://bank.com 的 iframe(银行网站);

  2. 通过脚本读取 iframe 中的 Cookie(含用户登录凭证);

  3. 将 Cookie 发送到恶意服务器,实现身份伪造。

因此,浏览器默认禁止跨域请求,以下情况都会触发跨域:

场景 协议 域名 端口 是否同源 说明
场景 1 http a.com 80 完全相同
场景 2 https a.com 80 协议不同(http → https)
场景 3 http b.com 80 域名不同(a.comb.com
场景 4 http a.com 8080 端口不同(80 → 8080)

3 跨域常见场景

在现代前端开发中,跨域问题几乎无处不在,以下是三大典型场景:

3.1 前后端分离项目的端口差异

  • 场景描述
    前端项目运行在 http://localhost:3000(Vue/React 开发服务器),后端 API 部署在 http://localhost:4000(Node/Java 服务器),端口不同导致跨域。

  • 请求示例
    前端通过 fetch('http://localhost:4000/api/users') 调用接口,浏览器报错:

javascript 复制代码
Cross-Origin Request Blocked: The Same Origin Policy disallows reading 
the remote resource at http://localhost:4000/api/users.

3.2 调用第三方 API 的域名差异

  • 场景描述
    前端页面需要请求第三方服务(如百度搜索建议、天气接口),域名不同触发跨域。

  • 案例:百度搜索自动补全
    前端请求 URL:https://www.baidu.com/sugrec?wd=a&cb=callback

    • 域名:www.baidu.com 与前端域名(如 your-site.com)不同,触发跨域。

    • 解决方案:使用 JSONP 或 CORS(需百度服务器配合)。

3.3 iframe 嵌套跨域页面的 DOM 操作限制

  • 场景描述

    a.com 的页面中嵌入 b.com 的 iframe,试图通过 JS 操作 iframe 中的 DOM 元素。

  • 代码示例

html 复制代码
<!-- a.com 的页面 -->
<iframe src="http://b.com" id="myIframe"></iframe>
<script>
  const iframe = document.getElementById('myIframe');
  // 以下操作会报错(跨域限制)
  console.log(iframe.contentWindow.document.body.innerHTML);
</script>
  • 错误提示
javascript 复制代码
Uncaught DOMException: Blocked a frame with origin "http://b.com" 
from accessing a cross-origin frame.

同源策略看似给开发增加了复杂度,但本质上是为了保护用户数据安全。理解跨域的核心在于掌握 "同源" 的定义(协议 + 域名 + 端口),以及浏览器的安全机制。理解跨域的本质后,我们才能更好地选择解决方案。

下一章将介绍第一个跨域方案 JSONP,敬请期待!

相关推荐
加班是不可能的,除非双倍日工资2 小时前
css预编译器实现星空背景图
前端·css·vue3
wyiyiyi3 小时前
【Web后端】Django、flask及其场景——以构建系统原型为例
前端·数据库·后端·python·django·flask
gnip3 小时前
vite和webpack打包结构控制
前端·javascript
excel4 小时前
在二维 Canvas 中模拟三角形绕 X、Y 轴旋转
前端
阿华的代码王国4 小时前
【Android】RecyclerView复用CheckBox的异常状态
android·xml·java·前端·后端
一条上岸小咸鱼4 小时前
Kotlin 基本数据类型(三):Booleans、Characters
android·前端·kotlin
Jimmy4 小时前
AI 代理是什么,其有助于我们实现更智能编程
前端·后端·ai编程
ZXT4 小时前
promise & async await总结
前端
Jerry说前后端4 小时前
RecyclerView 性能优化:从原理到实践的深度优化方案
android·前端·性能优化
画个太阳作晴天4 小时前
A12预装app
linux·服务器·前端