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

1 URL

URL(Uniform Resource Locator)是互联网上的一种资源的简洁标识。它是一种特定格式的字符串,可以指向互联网上的任何资源。当我们在浏览器中输入一个网址,它的结构其实暗含着多层信息。以http://username:[email protected]: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,敬请期待!

相关推荐
秋田君1 小时前
深入理解JavaScript设计模式之策略模式
javascript·设计模式·策略模式
萌萌哒草头将军2 小时前
🚀🚀🚀VSCode 发布 1.101 版本,Copilot 更全能!
前端·vue.js·react.js
GIS之路2 小时前
OpenLayers 图层叠加控制
前端·信息可视化
90后的晨仔2 小时前
ArkTS 语言中的number和Number区别是什么?
前端·harmonyos
菜鸡爱上编程2 小时前
React16,17,18,19更新对比
前端·javascript·reactjs·react
我命由我123452 小时前
VSCode - VSCode 转换英文字母的大小写
开发语言·javascript·ide·vscode·编辑器·html·软件工具
陈龙龙的陈龙龙3 小时前
uniapp 金额处理组件
前端·javascript·uni-app
我命由我123453 小时前
VSCode - VSCode 让未被编辑的标签页不被自动关闭
前端·javascript·ide·vscode·编辑器·html·js
Jimmy3 小时前
CSS 中操作移动,缩放和旋转
前端·css·react.js
layman05283 小时前
openeuler 虚拟机:Nginx 日志分析脚本
前端·javascript·nginx