bro,后端话事人,我真不想挂你在网上🫥

1,421 阅读11分钟

吊毛,看话事人挂网上请跳到目录:六、同源策略与 CORS:跨域的“边界墙”
我知道你就只想看这个 🤣🤣🤣

写前端写久了,我们对“请求-响应”这件事似乎再熟悉不过了。
但有时候,问题一旦细究起来,就会暴露出很多模糊地带——

从我在地址栏敲下 https://example.com 到页面渲染出来,这中间到底发生了多少事?

这篇文章就是一次“补坑”总结:
系统地串起我以前只记个大概、或者流程模糊的那些环节。
包括 DNS、TCP、TLS、HTTP 请求、缓存、CORS、渲染 等关键阶段。
希望看完这篇后,你能更清楚:
浏览器每一次请求背后到底跑了多少复杂的机制。

这个问题别和我说了我都表达清楚了.gif


一、从用户敲下 URL 开始:浏览器的准备工作

当你在地址栏输入 https://example.com/path?x=1 并敲下回车,浏览器启动“导航流程(navigation)”。

在真正“发请求”之前,它会做很多本地准备:

  1. 解析 URL:分解出协议、主机、端口、路径、查询参数。

  2. 检查本地缓存

    • 是否被 Service Worker 控制?
    • 是否有强缓存命中?
      命中就直接返回缓存结果,连服务器都不会打扰。
  3. 安全检查:比如 HTTPS 页面里引用 HTTP 资源会被拦截(混合内容)。

  4. 预优化动作
    <link rel="preconnect">dns-prefetchpreload 等会提前准备网络连接。

所以,用户“回车” ≠ 马上发请求,
浏览器其实先在本地忙活一阵。


二、DNS:找到目标服务器的地址

example.com 只是个名字,真正通信还得找到它的 IP。

浏览器不知道example.com 是哪台服务器,于是需要先做一步:把 "example.com" 翻译成 IP 地址(比如 47.243.26.11,ipv4或者ipv6地址) 当你访问一个网站,比如:example.com/ 这个网站的前端文件(HTML、JS、CSS)和后端接口(API)实际上都放在服务器上(即主机) 。可以类比成:

你本地浏览器是「客人」,
服务器是「饭店」,
域名是「饭店的门牌号」。

浏览器访问域名 → DNS 查出 IP → 实际上就是去找那台服务器(主机)。

DNS 解析流程一般是:

  1. 查浏览器自己的 DNS 缓存(最近访问的域名会缓存几分钟)。
  2. 查操作系统缓存或 hosts 文件。
  3. 若都没有,再发起 DNS 查询(通过本地 DNS、DoH、DoT 等)。

解析结果可能有多个 IP(例如 IPv4/IPv6),操作系统会根据策略决定优先顺序。

优化建议:

  • 使用 CDN(就近访问)
  • 启用 dns-prefetch 提前解析
  • 合理设置 DNS TTL,兼顾灵活与缓存

不知道大伙公司规模怎么样,一般大型公司,部署这一块主要由后台和前端专门负责部署得大哥去处理,其中还有就是CI/CD流程,持续集成,持续交付,前几年我也不是很了解,现在这个CI/CD流程可以自己去创建了,gitlab,github,或者Jenkins等等。

  • 网站放在服务器上(主机)。

  • 域名只是找服务器的地址。

  • 部署就是把你的代码放上服务器让人访问。

  • 堡垒机是跳板机,用来安全地登录服务器,不运行网站本身。(登录堡垒机 → 跳转生产机 → 拉取最新代码 → 打包部署 CI/CD简化了这个过程

image.png


三、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 握手阶段:

  1. 浏览器 → 服务器:发送 ClientHello,告诉支持的加密算法、TLS 版本、SNI(要访问的域名)。
  2. 服务器 → 浏览器:返回证书链、公钥、协商参数。
  3. 浏览器验证证书合法性(CA、域名、过期时间、撤销状态)。
  4. 双方协商出对称密钥,用于后续加密通信。

之后,数据就加密传输,防止被中间人窃听或篡改。

优化建议:

  • 使用 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)

面试官:如何解决跨域问题?

页面仔:

  1. postmessage
  2. script (get 请求)
  3. proxy代理
  4. 后端设置响应头 允许跨域,nginx代理
  5. 找后端,前端不解决跨域问题 (大部分跨域问题我们前端都不解决得吧,我感觉我最多也就是本地调试可能用下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 方法。

通常响应头里面都会包含上面得一个配置

平常我们页面仔请求经常会遇到接口不通或者返回不对得情况,我自己通常这样子排查得

  1. 是否跨域
  2. 请求url api地址是否正确
  3. 请求方式 get/post 是否正确
  4. 请求参数是否正确

注意请求参数一般两种形式:

常规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

这些头信息直接影响后续缓存与跨域行为。


八、浏览器接收响应并处理缓存逻辑

服务器返回响应后,浏览器做几件事:

  1. 检查状态码:200、301、304、404……

  2. 若是重定向(3xx),自动跟随 Location 发新请求。

  3. 检查缓存:

    • 强缓存(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 默认阻塞解析,除非加上 deferasync
  • 图片和视频不阻塞首次绘制,但影响 LCP。(老生常谈了,web页面使用CDN)

优化建议:

  • 将关键 CSS 内联。
  • 使用 <script defer>
  • 使用 preconnectpreload 加速关键资源。

十、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 -v
  • dig / 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想出来得这些东西,感觉每个点都至关重要呀。

9a84bf6b0b8bde8a08a02c54011f3fdb.jpeg