吊毛,看话事人挂网上请跳到目录:六、同源策略与 CORS:跨域的“边界墙”
我知道你就只想看这个 🤣🤣🤣
写前端写久了,我们对“请求-响应”这件事似乎再熟悉不过了。
但有时候,问题一旦细究起来,就会暴露出很多模糊地带——
从我在地址栏敲下
https://example.com到页面渲染出来,这中间到底发生了多少事?
这篇文章就是一次“补坑”总结:
系统地串起我以前只记个大概、或者流程模糊的那些环节。
包括 DNS、TCP、TLS、HTTP 请求、缓存、CORS、渲染 等关键阶段。
希望看完这篇后,你能更清楚:
浏览器每一次请求背后到底跑了多少复杂的机制。
一、从用户敲下 URL 开始:浏览器的准备工作
当你在地址栏输入 https://example.com/path?x=1 并敲下回车,浏览器启动“导航流程(navigation)”。
在真正“发请求”之前,它会做很多本地准备:
-
解析 URL:分解出协议、主机、端口、路径、查询参数。
-
检查本地缓存:
- 是否被 Service Worker 控制?
- 是否有强缓存命中?
命中就直接返回缓存结果,连服务器都不会打扰。
-
安全检查:比如 HTTPS 页面里引用 HTTP 资源会被拦截(混合内容)。
-
预优化动作:
<link rel="preconnect">、dns-prefetch、preload等会提前准备网络连接。
所以,用户“回车” ≠ 马上发请求,
浏览器其实先在本地忙活一阵。
二、DNS:找到目标服务器的地址
example.com 只是个名字,真正通信还得找到它的 IP。
浏览器不知道example.com 是哪台服务器,于是需要先做一步:把 "example.com" 翻译成 IP 地址(比如 47.243.26.11,ipv4或者ipv6地址)
当你访问一个网站,比如:example.com/ 这个网站的前端文件(HTML、JS、CSS)和后端接口(API)实际上都放在服务器上(即主机) 。可以类比成:
你本地浏览器是「客人」,
服务器是「饭店」,
域名是「饭店的门牌号」。
浏览器访问域名 → DNS 查出 IP → 实际上就是去找那台服务器(主机)。
DNS 解析流程一般是:
- 查浏览器自己的 DNS 缓存(最近访问的域名会缓存几分钟)。
- 查操作系统缓存或
hosts文件。 - 若都没有,再发起 DNS 查询(通过本地 DNS、DoH、DoT 等)。
解析结果可能有多个 IP(例如 IPv4/IPv6),操作系统会根据策略决定优先顺序。
优化建议:
- 使用 CDN(就近访问)
- 启用
dns-prefetch提前解析 - 合理设置 DNS TTL,兼顾灵活与缓存
不知道大伙公司规模怎么样,一般大型公司,部署这一块主要由后台和前端专门负责部署得大哥去处理,其中还有就是CI/CD流程,持续集成,持续交付,前几年我也不是很了解,现在这个CI/CD流程可以自己去创建了,gitlab,github,或者Jenkins等等。
-
网站放在服务器上(主机)。
-
域名只是找服务器的地址。
-
部署就是把你的代码放上服务器让人访问。
-
堡垒机是跳板机,用来安全地登录服务器,不运行网站本身。(登录堡垒机 → 跳转生产机 → 拉取最新代码 → 打包部署
CI/CD简化了这个过程)
三、TCP / QUIC:打通传输层的“电话线”
拿到 IP 后,浏览器要建立连接:
- HTTP/1.1 & HTTP/2 → 走 TCP
三次握手:SYN → SYN/ACK → ACK - HTTP/3 → 走 QUIC(基于 UDP),
握手更快,还能在丢包时单独恢复流。
浏览器会尽量复用已有连接(keep-alive / 连接池),
避免重复握手的延迟。
小贴士:
TCP 握手+TLS 握手在 HTTP/1.1 上通常需要两轮 RTT,
而 QUIC(HTTP/3)可直接 0-RTT 建连,速度飞快。
四、TLS 握手:安全信道的建立
如果是 HTTPS,接下来进入 TLS 握手阶段:
- 浏览器 → 服务器:发送 ClientHello,告诉支持的加密算法、TLS 版本、SNI(要访问的域名)。
- 服务器 → 浏览器:返回证书链、公钥、协商参数。
- 浏览器验证证书合法性(CA、域名、过期时间、撤销状态)。
- 双方协商出对称密钥,用于后续加密通信。
之后,数据就加密传输,防止被中间人窃听或篡改。
优化建议:
- 使用 TLS 1.3(减少握手延迟)
- 启用 OCSP stapling
- 配置 HSTS,强制所有访问走 HTTPS
简单理解就是https比http多了一层tls/ssl协议层,然后https需要付费购买,证书会存在过期情况。
五、构造并发送 HTTP 请求
连接准备就绪后,浏览器才真正发出 HTTP 请求。
例如:
GET /path?x=1 HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0 ...
Accept: text/html,application/xhtml+xml
Accept-Encoding: gzip, deflate, br
Cookie: session=abc123
Connection: keep-alive
一些关键点:
Host:用于虚拟主机,HTTP/1.1 必需。Accept-Encoding:告诉服务器浏览器能解压哪些格式。Cookie:若匹配域名与路径,就会自动携带。Referer&Origin:标明请求来源(CORS 校验用)。
如果是 fetch 或 XHR,还可能设置:
fetch(url, { credentials: 'include', mode: 'cors' })
六、同源策略与 CORS:跨域的“边界墙”
浏览器的安全模型很严格——
不同 源(协议+域名+端口) 的脚本不能随意访问彼此资源。
这叫 同源策略 (SOP) 。
为了解决合法跨域访问,诞生了 CORS (Cross-Origin Resource Sharing) 。
面试官:如何解决跨域问题?
页面仔:
- postmessage
- script (get 请求)
- proxy代理
- 后端设置响应头 允许跨域,nginx代理
- 找后端,前端不解决跨域问题 (大部分跨域问题我们前端都不解决得吧,我感觉我最多也就是本地调试可能用下proxy)
响应头后端设置跨域
我之前公司有一个后端(不是想把他挂网上),他是个老后端了,出现跨域问题啥的,他不知道嘞,有一次项目部署,他勾⑧啥也不看,nginx不配置,响应头是空的,所以跨域了噻,遇到这种问题测试问他,他就说找前端,然后俺还得屁颠屁颠去给他说情况,然后改nginx配置。
做事情不沟通,不看需求,印象最深的是一个需求我给他说接口要什么字段,然后还有就是一个请求我让他返回user_id,他非要说不规范,要admin_id,一个几年前得老项目,做事情不配合,不自测,代码一推完事,有问题就说我的代码没有bug,然后踢皮球丢给前端,然后不出所料,上次优化,他被优化了,被优化之后呀,还有留下得bug,我反复提醒他登录得另外一个项目接口返回加user_id,也没加,因为我们后台登录统一换成sso授权登录了(他是后端话事人,没想到吧,在公司干了快4年了),希望这个案例大伙引以为戒,不管前端还是后端😶🌫️😶🌫️😶🌫️
access-control-allow-headers: Token,Authorization,Origin,X-Requested-With,Content-Type,Accept
access-control-allow-methods:GET,POST,OPTIONS
access-control-allow-origin:*
-
允许所有域访问(
*)。 -
允许客户端在请求中带上这些额外头。
-
支持 GET / POST / OPTIONS 方法。
通常响应头里面都会包含上面得一个配置
平常我们页面仔请求经常会遇到接口不通或者返回不对得情况,我自己通常这样子排查得
- 是否跨域
- 请求url api地址是否正确
- 请求方式 get/post 是否正确
- 请求参数是否正确
注意请求参数一般两种形式:
常规json格式
表单参数(FormData格式)
请求头
'content-type' : 'application/json'
'Content-Type': 'application/x-www-form-urlencoded'
预检请求(Preflight)
对于复杂请求(PUT、DELETE、自定义头等),
浏览器先发一个 OPTIONS 请求询问是否允许:
Access-Control-Allow-Origin: https://app.com
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: Content-Type, X-Token
Access-Control-Allow-Credentials: true
Access-Control-Max-Age: 86400
如果服务端同意,才会发送真正的请求。
注意:
- CORS 是浏览器在前端限制的,服务器端其实照样接收请求。
- 带凭证(cookie)的跨域请求,
Access-Control-Allow-Origin不能用*。
七、服务器处理请求
服务端收到请求后,进入它的世界:
路由 → 鉴权 → 业务逻辑 → 数据库 → 响应。
返回示例:
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 4521
Cache-Control: public, max-age=3600
ETag: "abc123"
Last-Modified: Wed, 12 Nov 2025 08:00:00 GMT
Set-Cookie: session=xyz; HttpOnly; Secure; SameSite=Lax
Access-Control-Allow-Origin: https://app.com
这些头信息直接影响后续缓存与跨域行为。
八、浏览器接收响应并处理缓存逻辑
服务器返回响应后,浏览器做几件事:
-
检查状态码:200、301、304、404……
-
若是重定向(3xx),自动跟随 Location 发新请求。
-
检查缓存:
- 强缓存(Cache-Control / Expires)
- 协商缓存(ETag / Last-Modified)
强缓存示例:
Cache-Control: max-age=3600, public
在 1 小时内都不会重新请求。
协商缓存:
If-None-Match: "abc123"
If-Modified-Since: Wed, 12 Nov 2025 08:00:00 GMT
若未修改,服务器返回 304 Not Modified。
缓存类型:
| 类型 | 特点 |
|---|---|
| Memory Cache | 热缓存,关闭标签页失效 |
| Disk Cache | 持久化缓存 |
| Service Worker Cache | 自定义逻辑,离线可用 |
强缓存和协商缓存去找找文章看看尼,我好像没遇到过使用场景,还有一个离线缓存,后边我去看看这玩意咋实现得
九、渲染:HTML → DOM → 视觉页面
拿到 HTML 后,渲染引擎开始边下载边解析:
HTML → DOM
CSS → CSSOM
DOM + CSSOM → Render Tree
Layout → Paint → Composite
JS、CSS 的加载顺序直接影响渲染时机:
- CSS 会阻塞渲染。
- JS 默认阻塞解析,除非加上
defer或async。 - 图片和视频不阻塞首次绘制,但影响 LCP。(老生常谈了,web页面使用CDN)
优化建议:
- 将关键 CSS 内联。
- 使用
<script defer>。 - 使用
preconnect、preload加速关键资源。
十、HTTP/2 与 HTTP/3:更快的传输协议
HTTP/2
- 多路复用(一个 TCP 连接跑多个请求)
- 头部压缩(HPACK)
- 优先级控制
HTTP/3
- 基于 QUIC(UDP)
- 不受 TCP 队头阻塞影响
- 支持 0-RTT 握手
简单理解:
HTTP/3 是让网络“更像多车道高速公路”的协议革命。HTTP/3协议得目前我还没看到过,说的是一些大厂在用了,接口响应速度肯定很快,如果以后都特别快了,是不是loading都不需要了😁,当然肯定是要的了,因为有弱网环境😶🌫️。
十一、安全与认证
常见安全头:
| Header | 功能 |
|---|---|
Strict-Transport-Security | 强制 HTTPS |
Content-Security-Policy | 防止 XSS/注入 |
X-Frame-Options | 禁止被 iframe 嵌套 |
Cross-Origin-Opener-Policy / Cross-Origin-Embedder-Policy | 开启跨域隔离 |
Cookie 属性同样重要:
HttpOnly:JS 不能访问Secure:仅 HTTPS 发送SameSite:防跨站请求伪造(CSRF)
安全也是老生常谈了,前端一般做法就是登录(h5页面就是app通常通过url加密)获取到token,请求头设置token(authorization)然后带着参数传给后端,再安全一点就是加会话签名sig等等(sso授权登录)。
十二、调试与优化建议
| 问题 | 检查点 |
|---|---|
| 页面加载慢 | DNS、TCP、TLS、TTFB、阻塞资源 |
| 缓存失效 | Cache-Control、ETag、Vary、Set-Cookie |
| CORS 报错 | 检查预检响应头 |
| Cookie 不发送 | 检查 SameSite、Secure、credentials |
| 证书异常 | 查看证书链、OCSP 状态 |
| Service Worker 异常 | 检查拦截逻辑与缓存更新策略 |
常用调试工具:
- Chrome DevTools(Network / Security)
curl -vdig/nslookup- Lighthouse 性能分析
十三、整体时序复盘
用户输入 URL
↓
DNS 解析
↓
TCP / QUIC 握手
↓
TLS 握手(HTTPS)
↓
发送 HTTP 请求
↓
服务器处理 & 返回响应
↓
浏览器检查缓存 / CORS
↓
HTML 解析 → 渲染页面
整个过程,从用户动作到像素出现在屏幕,
往往只发生在几百毫秒内。
但每一步都隐藏着大量可优化的细节。
十四、工程实践清单(总结)
启用 HTTPS(TLS 1.3)
使用 CDN、preconnect、DNS-prefetch
静态资源指纹化 + 长缓存(max-age=31536000, immutable)
合理压缩(gzip / br)
defer/async 异步加载脚本
正确配置 CORS(尤其带凭证场景)
擅用 Service Worker 做离线缓存
速度、稳定、安全、缓存命中率 ——
这四个关键词几乎涵盖了前端网络层的所有优化核心。
十五、写在最后:当你再看“请求 → 响应”
从 DNS 到渲染,这是一条看似简单的链路,
但却连接着浏览器、网络、服务器、安全、协议等整个体系。
前端工程师如果只停留在调用接口、渲染数据(快去学习nodejs或者go服务器语言搞全栈,我是不学了,后边看看react-native得了), 就会在排查性能与跨域问题时寸步难行。
有好些中间层计算机基础和核心知识,这个玩意谁tm想出来得这些东西,感觉每个点都至关重要呀。