答案:认识HTTP协议与应用层定位
如果 HTTP 是有状态的(像微信聊天一样记住上下文),会带来什么好处和弊端?
好处:
如果 HTTP 像微信聊天一样有状态,服务器能记住航仔每次请求的历史。比如航仔第一次请求登录后,后续访问员工查询系统、OA 审批、风速的航班调度页面,服务器都认得他是谁,无需反复提交用户名密码。这能大幅减少重复验证开销,提升用户体验,类似图妹打开飞翔内部系统时不用每次都扫码登录。
弊端:
但这也带来严重问题。首先,服务器必须保存每个客户端的会话状态,当星宇、靓晴、鸣哥、雁姐等上万员工同时在线时,内存和存储压力巨大。其次,有状态协议难以做负载均衡——凌叔部署了 3 台服务器做集群,如果航仔第一次请求落在 A 服务器,第二次落在 B 服务器,B 服务器不认识他,就会报错。最后,一旦某台服务器宕机,该服务器上所有会话全部丢失,波比填了一半的报销单可能就没了。
因此,HTTP 选择无状态设计,通过 Cookie/Session/Token 等机制把"状态"交给客户端或外部存储(如 Redis)来管理,既保持了协议简单,又通过架构手段弥补了无状态的不足。凌叔常说:"协议不做的事,架构来做。"
为什么浏览器访问一个网页时,往往会产生多个 HTTP 请求?
浏览器访问一个网页,本质上不是只下载一个 HTML 文件,而是要把页面所需的全部资源都拉取下来。
以飞翔公司官网为例:
- HTML 骨架:浏览器先请求
http://feixiang.net/index.html,拿到页面的基本结构。 - CSS 样式:HTML 中引用了
style.css,浏览器再发一个请求获取它,用来渲染航仔设计的蓝色飞翔主题。 - JavaScript 交互:引用了
app.js,浏览器再请求,实现波比点击"查询航班"按钮时的动态效果。 - 图片资源:图妹上传的公司 Logo
logo.png、雁姐拍的团队照片team.jpg,每个图片都是独立请求。 - 字体、视频、API 数据:如果页面嵌入了风速的实时天气视频或星宇的航班动态接口,还会产生更多请求。
用 Chrome 开发者工具可以看到这个过程:
# 使用 curl 模拟浏览器获取 HTML
curl -I http://feixiang.net/index.html
# 响应中包含对其他资源的引用
# 浏览器解析 HTML 后,会自动发起后续请求:
# GET /style.css
# GET /app.js
# GET /logo.png
# GET /api/flights
现代浏览器会并行发起 6~8 个 TCP 连接来同时下载这些资源,并通过 HTTP/2 的多路复用进一步优化。所以打开一个网页产生几十个 HTTP 请求是常态,不是异常。
飞翔公司的员工查询系统应该使用静态网页还是动态网页?为什么?
飞翔公司的员工查询系统必须使用动态网页。
原因分析:
员工查询系统的核心功能是:波比输入工号,查询自己的考勤、薪资、假期余额;翼王作为部门主管,查询整个团队的绩效;凌叔查看服务器运维值班表。这些数据因人而异、因时而变——星宇今天查还剩 3 天年假,下周再查可能只剩 1 天。
静态网页(如纯 HTML 文件)内容固定,无法根据用户身份和实时数据变化。如果硬做成静态页面,意味着要为每个员工生成一个独立 HTML 文件,上万员工的任何数据变动都要重新生成页面,完全不现实。
动态网页则不同。当空少登录系统时,服务器(比如凌叔部署的 Nginx + Node.js 后端)会:
- 验证空少的身份(从 Cookie/Token 中读取)
- 查询数据库获取空少的个人信息
- 把数据填充到 HTML 模板中
- 返回给浏览器
# 伪代码示意:动态生成查询结果
def query_employee(request):
user_id = request.session.get('user_id') # 获取当前登录用户
employee = db.query("SELECT * FROM employees WHERE id = ?", user_id)
return render_template('profile.html', employee=employee)
当然,系统中某些部分可以用静态网页加速,比如飞翔公司的企业文化介绍页、图妹设计的首页 Banner,这些不常变动的内容可以用 CDN 缓存。但员工查询这种"千人千面"的功能,动态网页是唯一合理的选择。