HTTP协议
TCP/IP 协议族
TCP/IP 协议族
是Internet最基本的协议,HTTP协议是它的一个子集
。TCP/IP协议族按层次分为以下四层
应用层
负责处理网络应用程序之间的通信,如
FTP
协议(文件传输),HTTP
协议(Web通信),DNS
协议(域名系统)。传输层
提供处于网络连接中两台计算机之间的数据传输所使用的协议,如
UDP
协议(面向无连接,高效轻便),TCP
协议(全双工通信,稳定可靠)。网络层
规定了数据通过怎样的传输路线到达对方计算机传送给对方,如
IP
协议。链路层
用来处理连接网络的硬件部分(如网卡,光纤等)。
WEB应用的通信传输的一般流程:
HTTP协议特点
无状态
:每一次请求都是独立的,请求结束不会记录连接的任何信息。明文传输
:直接将明文信息暴露给了外界,存在一定安全隐患。基于TCP协议
:HTTP 1.1之后默认开启持久连接(Connection:Keep-Alive),即多次HTTP请求只需使用一个TCP连接,减少了建立和关闭连接的消耗和延迟。
持久连接(长连接)
优点:
- 减少CPU及内存的使用,因为不需要经常建立和关闭连接
- 支持管道化的请求及响应模式
- 减少网络堵塞,因为减少了TCP请求
- 减少了后续请求的响应时间,因为不需要等待建立TCP、握手、挥手、关闭TCP的过程
- 发生错误时,也可在不关闭连接的情况下进行错误提示
缺点:
长时间保持长连接,会比较消耗服务器资源
解决方法:
(1)客户端请求头声明:
Connection: close
,即关闭长连接模式。(2)服务端配置:如Nginx,设置
keepalive_timeout
设置长连接超时时间,keepalive_requests
设置长连接请求次数上限。队头阻塞问题
当 http 开启长连接时,后续多个请求可共用一个 TCP 连接,但
同一时刻只能处理一个请求
,那么当前请求耗时过长的情况下,其它的请求只能处于阻塞状态,也就是著名的队头阻塞问题。解决方法:
(1)一个域名允许分配多个长连接,现在浏览器标准中一个域名并发连接可以有6~8个。
(2)可使用多个域名。
(3)HTTP2.0支持
多路复用
,可以在一个TCP连接中发送多个请求。
HTTP报文
请求报文
请求报文由以下四部分组成:
- 请求行:包含http请求方法,请求地址,http协议以及版本。
- 请求头:以键值对形式存在的字段,展示该请求的一些规则参数。
- 空行:用来区分请求头与请求体,因为请求头都是键值对的格式,当解析遇到空行时,服务端就知道下一个不再是请求头部分,就该当作请求体来解析了。
- 请求体:请求资源所需要传递给服务器的数据。
常见请求头部:
字段 | 说明 | 示例 |
---|---|---|
Accept | 指定客户端能够接收的内容类型 | Accept: text/plain, text/html |
Accept-Charset | 浏览器可以接受的字符编码集。 | Accept-Charset: iso-8859-5 |
Accept-Encoding | 指定浏览器可以支持的web服务器返回内容压缩编码类型。 | Accept-Encoding: compress, gzip |
Accept-Language | 浏览器可接受的语言 | Accept-Language: en,zh |
Authorization | HTTP授权的授权认证信息,比如登录token | Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== |
Cache-Control | 指定请求和响应遵循的缓存机制,详见:Cache-Control。 | Cache-Control: no-cache |
Connection | 表示是否需要持久连接。(HTTP 1.1默认进行持久连接) | Connection: Keep-Alive |
Cookie | HTTP请求发送时,会把保存在该请求域名下的所有cookie值一起发送给web服务器。 | Cookie: $Version=1; Skin=new; |
Content-Length | 请求的内容长度 | Content-Length: 348 |
Content-Type | 请求的与实体对应的MIME信息,见Content-Type常见值。 | Content-Type: application/x-www-form-urlencoded |
Date | 请求发送的日期和时间 | Date: Tue, 15 Nov 2010 08:12:31 GMT |
Host | 指定请求的服务器的域名和端口号 | Host: www.baidu.com |
If-Modified-Since | 如果请求的部分在指定时间之后被修改则请求成功,未被修改则返回304代码。详见:协商缓存。 | If-Modified-Since: Sat, 29 Oct 2010 19:43:31 GMT |
If-None-Match | 如果内容未改变返回304代码,参数为服务器先前发送的Etag,与服务器回应的Etag比较判断是否改变。详见:协商缓存。 | If-None-Match: “737060cd8c284d8af7ad3082f209582d” |
Referer | 先前网页的地址,当前请求网页紧随其后,即来路 | Referer: www.baidu.com |
User-Agent | User-Agent的内容包含发出请求的用户信息 | User-Agent: Mozilla/5.0 (Linux; X11) |
响应报文
响应报文由以下四部分组成:
- 状态行:包含http协议以及版本,响应状态码。
- 响应头:以键值对形式存在的字段,展示该响应的一些规则参数。
- 空行:用来区分响应头与响应体,因为响应头都是键值对的格式,当解析遇到空行时,服务端就知道下一个不再是响应头部分,就该当作响应体来解析了。
- 响应体:服务端返回的资源信息。
常见响应头部:
字段 | 说明 | 示例 |
---|---|---|
Allow | 对某网络资源的有效的请求方法 ,不允许则返回405 | Allow: GET, HEAD |
Cache-Control | 告诉所有的缓存机制是否可以缓存及哪种类型,详见:Cache-Control | Cache-Control: no-cache |
Content-Encoding | web服务器支持的返回内容压缩编码类型。 | Content-Encoding: gzip |
Content-Language | 响应体的语言 | Content-Language: en,zh |
Content-Length | 响应体的长度 | Content-Length: 348 |
Content-Type | 返回内容的MIME类型,见Content-Type常见值。 | Content-Type: text/html; charset=utf-8 |
Date | 原始服务器消息发出的时间 | Date: Tue, 15 Nov 2010 08:12:31 GMT |
ETag | 请求变量的实体标签的当前值,详见:协商缓存。 | ETag: “737060cd8c284d8af7ad3082f209582d” |
Expires | 响应过期的日期和时间,详见:Expires。 | Expires: Thu, 01 Dec 2010 16:00:00 GMT |
Last-Modified | 请求资源的最后修改时间 | Last-Modified: Tue, 15 Nov 2010 12:45:26 GMT |
Location | 用来重定向接收方到非请求URL的位置来完成请求或标识新的资源 | Location: http://www.baidu.com/test.html |
refresh | 应用于重定向或一个新的资源被创造,在5秒之后重定向(由网景提出,被大部分浏览器支持) | Refresh: 5; url=http://www.zcmhi.com/archives/94.html |
Set-Cookie | 设置Http Cookie | Set-Cookie: UserID=JohnDoe; Max-Age=3600; Version=1 |
常见响应状态码:
状态码 | 说明 |
---|---|
200 OK | 请求成功 |
204 Not Content | 请求成功,但没有返回任何数据。响应报文内不包含实体的主体部分。 |
301 Moved Permanently | 永久性重定向,表示资源已被分配了新的 URL。例如网站从http迁移到https,则原http url应返回301 |
302 Found | 临时性重定向,表示资源临时被分配了新的 URL |
304 Not Modified | 当协商缓存命中时会返回这个状态码,表示请求资源未修改,可以使用缓存的资源。 |
400 Bad Request | 请求报文存在语法错误 |
401 Unauthorized | 没有权限访问,需要有通过 HTTP 认证的认证信息。例如需要登录才可访问 |
403 Forbidden | 表示对请求资源的访问被服务器拒绝,例如访问权限不够 |
404 Not Found | 在服务器上没有找到请求的资源 |
405 Method Not Allowed | 客户端请求中的方法被禁止,比如服务器仅支持GET方式,请求时却使用了POST,属于客户端错误。 |
500 Internal Server Error | 服务器内部错误 |
501 Not Implemented | 仅当服务器不支持现有的某个请求方法并且无法或不愿将其转为其他方法时才会使用,属于服务器错误。 |
502 Bad Gateway | 网关错误 |
503 Service Unavailable | 服务临时不可用,表明服务器暂时处于超负载或正在停机维护,无法处理请求。 |
504 Gateaway Timeout | 网关超时,是代理服务器等待应用服务器响应时的超时。 |
Content-Type常见值
- text/plain:纯文本格式,不包含任何HTML或其他格式的标记。
- text/html:HTML文档格式,用于表示包含HTML标签的文本。
- application/json:JSON数据格式,一种轻量级的数据交换格式。
- application/xml:XML数据格式,用于编码文档的标记语言。
- application/x-www-form-urlencoded:表单数据最常见的编码类型,不支持二进制文件数据。表单数据被编码为key/value格式发送到服务器。
- multipart/form-data:当表单需要上传文件时,通常会使用此类型。它允许在HTTP请求中发送二进制数据。
请求方法
- GET:获取资源
- POST:传输资源,通常会造成服务器资源的修改
- PUT:更新资源
- DELETE:删除资源
- HEAD:用于获取报文首部,不返回报文主体
- OPTIONS:列出请求资源支持的请求方法,用来跨域请求
其中最常用的是GET
和POST
方法,它们的区别主要有:
行为 | GET | POST |
---|---|---|
浏览器回退 | 无影响 | 会再次发起请求 |
是否会被缓存 | 是 | 否 |
被浏览器保存历史记录 | 是 | 否 |
传递参数长度限制 | 是 | 否 |
参数传递方式 | 直接放在URL后面 | 放在请求体中 |
HTTP代理
代理服务器就是客户端和服务端之间的“中间商”,即HTTP请求通过代理服务器转发给服务器,再将服务器的响应返回给客户端的行为。
HTTP代理的主要作用:
突破访问限制
许多网站会对请求访问的IP地址进行检测,对于部分地区的IP地址会直接拒绝访问。通过使用HTTP代理服务器,可以突破这种IP封锁。
提高安全性
可以通过这种方式隐藏用户(正向代理)或服务器(反向代理)的IP,免受攻击。还可以对数据过滤,对非法IP限流(类似防火墙)。
缓存代理
将内容缓存到代理服务器,使得客户端可以直接从代理服务器获得而不用到源服务器那里,如响应头设置
Cache-Control:public
。可加速网路访问,缓解真实服务器压力。关于缓存详见Cache-Control
正向代理
工作在客户端
的代理为正向代理。使用正向代理的时候,需要在客户端配置需要使用的代理服务器。客户端向代理服务器发出请求,并指定目标访问服务器,然后,代理服务器向源服务器转交需求,并将获得的内容返回给客户端。
- 特点:服务端不知道客户端真实IP,
客户端知道服务端真实ip
- 常见场景:抓包工具,VPN科学上网等工具
反向代理
工作在服务端
的代理为反向代理。是客户端向反向代理发出请求,反向代理服务器收到需求后判断请求走向何处,然后再将结果反馈给客户端。
- 特点:服务端知道客户端真实IP,
客户端不知道服务端真实ip,只知道代理服务器ip
- 常见场景:Nginx解决跨域
前端本地开发服务器proxy属于正向还是反向代理?
从前端开发者角度来看,设置proxy是源于开发者知道服务端真实ip,看似应该是正向代理。但是正确角度应该是站在浏览器和页面的角度,它是不知道服务端真实ip的。所以它应该是反向代理吗?
尽管前端工具的 proxy 配置可以代理请求到多个服务器,从而在某些场景下具备类似反向代理的功能,但其本质和主要用途依然是解决开发过程中的跨域问题。真正的反向代理(如 Nginx)在功能和应用场景上更加广泛和复杂,主要用于生产环境中的负载均衡、安全性和性能优化。 因此,前端工具中的 proxy 配置在某些特定情况下可以被视为一种简单的反向代理,但它们在设计目的、应用场景和功能上与传统的反向代理有显著区别。
HTTP 2.0
- 使用新的
二进制协议
,不再是纯文本,避免文本歧义,缩小了请求体积。 多路复用
,允许通过单一的HTTP2.0连接同时发起多重的请求-响应消息,解决了HTTP队头阻塞问题。- 允许
服务端主动推送
数据给客户端 头部压缩
:之前是通过Content-Encoding8对请求体进行压缩,而HTTP/2 针对头部字段,采用了压缩算法HPACK进行压缩。
HPACK算法:服务器和客户端之间建立哈希表,将用到的字段存放在这张表中,那么在传输的时候对于之前出现过的值,只需要把索引(比如0,1,2,...)传给对方即可,对方拿到索引查表就行了。
HTTPS
HTTPS 是超文本传输安全协议,即HTTP + SSL/TLS
。
与HTTP区别:
- HTTP是
明文传输
,不安全的,HTTPS是加密传输
,安全的多。 - HTTP标准端口是
80
,HTTPS标准端口是443
。 - HTTP不用认证证书免费,HTTPS需要
认证证书要钱
。 - 连接方式不同,HTTP三次握手,HTTPS中会在三次握手基础上新增TLS四次握手,详见这里。
- HTTP在OSI网络模型中是在
应用层
,而HTTPS的TLS是在传输层
。 - HTTP是
无状态
的,HTTPS是有状态
的(涉及身份验证)。 - HTTP网页无法访问HTTPS资源,反之可以(但有安全提示)。
既然HTTPS这么安全可靠为什么不一直用HTTPS?
- 加密通信会消耗更多的CPU和内存资源。
- 购买证书需要一定的开销成本。
常见通信方式
通信方式 | 长轮询 | 短轮询 | WebSocket | SSE(Server-Sent-Event) |
---|---|---|---|---|
通信协议 | HTTP | HTTP | TCP | HTTP |
机制 | 客户端发送请求,服务器维持连接直到有数据或超时才响应,客户端收到响应后立即重新发起请求,如此反复。 | 客户端定时发送请求,服务器立即响应(无论是否有数据)。 | 全双工通信 ,客户端与服务器建立持久连接,双方可随时主动发送数据。 | 服务器单向推送数据 (客户端→服务器需走HTTP),基于HTTP长连接。 |
优点 | - 实时通信 - 无需客户端不断发起请求,降低了流量浪费。 | - 实现简单 - 兼容性好(所有浏览器支持) | - 实时性极佳 - 低延迟 - 节省带宽(无HTTP头开销) -可发送文本和二进制数据 - 不受http同源策略限制, 默认可跨域 | - 实时性较好 - 支持自动重连 - 轻量级 |
缺点 | - 服务器连接占用资源 - 实现复杂(需处理超时和重连) | - 高频请求浪费资源 - 实时性差(依赖轮询间隔) | - 实现复杂 - 需服务器支持WebSocket协议 - 不支持自动重连,需要自行处理 | - 仅支持服务器→客户端单向通信 - 部分浏览器兼容性差(如IE不支持) - 仅支持发送文本 |
适用场景 | 中等实时性需求,如聊天应用、股票价格更新。 | 简单场景,如定期检查通知、低实时性需求。 | 高实时性交互场景,如在线游戏、实时协作编辑、视频会议。 | 服务器主动推送场景,如大语言模型的流式输出,新闻推送、实时日志监控、股票行情。 |
总结
- 实时性:WebSocket > SSE ≈ 长轮询 > 短轮询。
- 资源消耗:短轮询(高频请求) > 长轮询(连接占用) > WebSocket/SSE(持久连接)。
- 兼容性:短轮询 > 长轮询 > SSE > WebSocket(需现代浏览器支持)。
- 选择建议:
- 需要双向实时通信 → WebSocket。
- 只需服务器推送 → SSE(更简单)。
- 低实时性需求 → 短轮询/长轮询(兼容老旧系统)。