Appearance
HTTP 和 Web
浏览器找到服务器之后,还得有一套双方都懂的"说话格式"——这就是 HTTP。浏览器发请求、服务端回响应,页面、图片、接口数据全靠这一来一回传。打个比方,TCP 像是拉通了双方的电话线,TLS 负责给通话加密,HTTP 则是双方约定的语言——说什么、怎么回、错了怎么办。
一、请求与响应
HTTP 请求本质上就是一段文本。一个最简单的 GET 请求长这样:
http
GET /docs/index.html HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0
Accept: text/html第一行是请求行——GET 是方法,/docs/index.html 是路径,HTTP/1.1 是协议版本;后面几行都是 Header,Host 必带(因为同一台服务器可能挂多个站,要靠它区分),User-Agent 告诉服务端是什么浏览器,Accept 说明客户端想收什么格式。
服务端返回的响应也是类似结构:
http
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Cache-Control: max-age=300
<html>...</html>第一行 200 OK 是状态码和状态文本;接着是响应头,告诉客户端响应体是什么格式、要不要缓存、缓存多久;空一行之后是真正的响应体——这里是一段 HTML。
排查问题的时候,直接 curl -v https://www.example.com 就能把请求和响应的完整文本打出来,看着比浏览器 Network 面板更直观。
二、HTTP 方法
HTTP 方法告诉服务端这次请求想干什么——读、写、改还是删:
| 方法 | 干什么 | 典型场景 |
|---|---|---|
GET | 读资源 | 打开页面、查询列表、获取详情 |
POST | 创建或者提交 | 登录、提交表单、新建任务 |
PUT | 整体替换某个资源 | 更新一个对象的全部字段 |
PATCH | 局部更新 | 只改某一个字段 |
DELETE | 删除资源 | 删除任务、删除文件 |
浏览器打开页面绝大多数都是 GET。前端调后端接口时,路径会写成 /api/users、/api/tasks/123 这种样子——路径本身只是个名字,具体这个路径对应什么动作、由哪段代码处理,是后端路由决定的,跟方法名和路径都没有强绑定关系。所以光看一个 URL 不一定知道它是干啥的,得看代码或者接口文档。
三、Header
Header 是请求和响应里的"附加字段",信息量大,排查问题经常要看。常用的几个:
| Header | 干什么 |
|---|---|
Host | 访问的域名,Nginx 靠它分流 |
Content-Type | 请求体或响应体是什么格式(application/json、text/html、multipart/form-data) |
Authorization | 登录后的认证信息,通常是 Bearer <token> |
Cookie | 浏览器存的站点数据,登录态经常靠它 |
Cache-Control | 缓存策略,客户端和 CDN 都看这个 |
X-Forwarded-For | 代理转发之后保留的原始客户端 IP |
最后这个 X-Forwarded-For 是个坑点。请求经过 Nginx、负载均衡、网关之后,后端看到的"客户端 IP"其实是上一层代理的 IP,不是用户真实 IP。如果想拿真实 IP 做风控或者日志,要靠入口层在 Header 里塞 X-Forwarded-For 这种字段,后端读这个字段才行。如果入口没配,后端拿到的就是 LB 内网 IP,排查异常请求的时候会一脸懵。
四、状态码
状态码是服务端告诉客户端"这次请求处理得怎么样"。记一下范围就行:2xx 成功、3xx 重定向或缓存、4xx 客户端这边有问题、5xx 服务端这边有问题。
具体到常用的:
| 状态码 | 用户侧现象 | 大概率卡在哪 |
|---|---|---|
200 | 正常返回 | 没问题 |
301/302 | 自动跳到另一个地址 | 重定向配置,可能是 HTTP 跳 HTTPS、或者旧域名跳新域名 |
304 | 浏览器用了本地缓存 | 缓存命中,不是错误 |
400 | 请求参数格式不对 | 前端传错字段、JSON 格式坏掉 |
401 | 未登录或认证失败 | Token 过期、Cookie 没带 |
403 | 没权限 | 登录了但角色不够、IP 被拉黑 |
404 | 页面或接口不存在 | 路径错了、路由没配 |
500 | 后端处理时报错 | 应用代码异常、数据库连不上、下游服务挂 |
502 | 网关连接后端失败 | 后端实例没起来、端口不对、连接被拒绝 |
504 | 网关等后端超时 | 后端处理太慢、被入口层超时切了 |
排查时同样一个 404,根因可能完全不一样——前端路由配置错、Nginx location 没匹配上、后端路由没注册,都会让用户看到 404。502 则更具体一些,基本就是入口到后端这一段:upstream 端口配错、后端 Pod 没起来、Kubernetes Service 没有 Endpoints、后端进程崩了。看到 502,先去入口层(Nginx/Ingress)的 error log 看一眼,基本能直接定位。
五、登录状态
HTTP 协议本身是"无状态"的——服务端处理完一个请求就忘了,下一个请求过来服务端不认识你。但网站登录明显不能这样,你登录一次之后,关掉再打开浏览器还是登录态。靠的是 Cookie、Session、Token 这几种机制。
最经典的做法是 Cookie + Session:用户登录成功后,服务端生成一个会话 ID(Session ID),通过响应头里的 Set-Cookie 让浏览器存到 Cookie 里;浏览器后续请求会自动带上 Cookie,服务端拿到 Session ID 就能识别出这是哪个用户。Session 数据存在服务端(内存、Redis、数据库里),所以服务端重启或者多实例时不共享 Session,就会出现"刷新一下就掉登录"的问题。
前后端分离系统现在更常用 Token:登录接口成功后返回一个 Token(通常是 JWT),前端把 Token 存起来(localStorage 或者内存),后续每个请求在 Authorization Header 里带上 Bearer <token>。Token 不需要服务端保存会话,天然支持多实例和跨域,这也是为什么微服务架构基本都用 Token。
六、页面与接口
一个网站对外提供的东西大致分两类:静态资源和动态接口。
| 类型 | 具体是什么 | 放在哪里 |
|---|---|---|
| 静态资源 | HTML、CSS、JS、图片、字体 | Nginx、对象存储、CDN |
| 动态接口 | 用户数据、订单、任务、统计 | 后端应用 + 数据库 + 缓存 |
传统网站(比如 PHP、JSP 那个年代)是服务端直接拼好完整 HTML 再返回,前后端不分离。现在主流是前后端分离:浏览器先拉静态资源,JS 跑起来之后再调后端 API 拿 JSON 数据,前端渲染。
页面白屏的时候排查顺序:打开浏览器 Network 颜板,先看 HTML 是不是 200(不是的话基本是入口层问题);再看 JS/CSS 文件有没有 404(前端构建路径或者发布路径有问题);最后看 API 返回什么——401 是没登录、500 是后端炸了、CORS 报错是跨域没配。这一套流程走完,白屏问题基本能定位。