网络原理篇
列举 HTTP 状态码以及它们的含义
下面列举 web 开发中常见的 HTTP code:
- 200 (ok): 请求成功
- 204 (No Content): 请求成功,不需要附带实体内容 (body)
- 301 (Moved Permanently): 永久重定向。被请求的资源已永久移动到新位置
- 302 (Found): 临时重定向。请求的资源临时从不同的 URI 响应请求。由于这样的重定向是临时的,客户端应当继续向原有地址发送以后的请求。
- 400 (Bad Request): 请求参数有误
- 401 (Unauthorized): 当前请求需要用户验证
- 403 (Forbidden): 没有权限的操作。服务器已经理解请求,但拒绝执行。
- 404 (Not Found): 资源没有找到
- 500 (Internal Server Error): 服务端出现了错误
- 502 (Bad Gateway): 网关错误。此错误响应表明服务器作为网关需要得到一个处理这个请求的响应,但是得到一个错误的响应
- 503 (Service Unavailable): 服务器停止服务。常见原因是服务器因维护或重载而停机
- 504 (Gateway Timeout): 网关超时。当服务器作为网关,不能及时得到响应时返回此错误代码。
HTTP 的 GET 和 POST 请求有什么区别?
GET 和 POST 在浏览器上的表现会根据使用场景有各自的优缺点:
- GET 可以直接在浏览器上手动输入请求,在浏览器地址直接请求的 URL 在非匿名模式下会被浏览器记录下来的。这样用户可以通过历史记录来找回之前访问过的页面。反之,POST 不会在浏览器留下痕迹。
- GET 在浏览器地址上的长度是有限制的,POST 没有限制。
- GET 的请求一般可以被浏览器缓存
- 带云压缩的浏览器,比如 Opera mini/Turbo 2, 只有 GET 才能在服务器端被预取
但实际使用时 GET 和 POST 请求所进行的操作取决于服务端是如何解释的。比如一种极端情况就是:不管你是查询、删除、更新还是提交数据也好,所有请求一律使用 POST 来实现都没问题。但这种做法不符合主流的 RESTful APIs
设计规范,不建议这样做。
相关讨论参见: post 相比get 有很多优点,为什么现在的HTTP通信中大多数请求还是使用get?
有了解过 HTTP 缓存吗?
HTTP 缓存策略可分强缓存与协商缓存。这些机制通过 HTTP 头部字段来控制,可以有效减少网络延迟,提高网页加载速度,并减轻服务器的负载。
强缓存(Strong Caching)
强缓存不会向服务器发送请求,直接从缓存中读取资源。强缓存可以通过两个 HTTP 响应头实现:
Expires
Expires
是一个日期/时间,指示资源什么时候过期。如果请求的时间小于Expires
指定的时间,浏览器就直接使用缓存的资源。- 例如:
Expires: Wed, 21 Oct 2020 07:28:00 GMT
Expires
是 HTTP/1.0 的产物,依赖于客户端和服务器时间的一致性,因此不太可靠。
Cache-Control
Cache-Control
是一个更灵活的 HTTP/1.1 字段,用于定义资源的缓存策略。常见的值包括:max-age=<seconds>
:资源在被认为过期之前可以保留的最大时间(秒)。public
:指示响应可被任何缓存存储。private
:响应是为单个用户定制的,不能由共享缓存存储。no-cache
:强制每次请求直接发送到服务器,服务器会验证资源的有效性。no-store
:绝对禁止缓存。
- 例如:
Cache-Control: max-age=3600
如果这两个字段同时存在,Cache-Control
会优先于 Expires
。
协商缓存(Negotiated Caching)
当强缓存过期后,如果资源仍可使用,协商缓存将允许客户端与服务器之间进行“协商”,看是否可以继续使用缓存的资源。这主要通过以下两对 HTTP 头实现:
Last-Modified
和If-Modified-Since
Last-Modified
标记资源的最后修改时间。- 当资源过期并再次发起请求时,浏览器会发送
If-Modified-Since
,该值为之前Last-Modified
的值。 - 服务器比较时间,如果服务器资源未改变,则返回 HTTP 304(Not Modified),浏览器继续使用缓存。
ETag
和If-None-Match
ETag
是资源的特定版本的唯一标识符。如果资源过期,浏览器会在请求中包含If-None-Match
,其值为之前的ETag
。- 如果
ETag
仍然匹配,服务器返回 HTTP 304,浏览器使用缓存的资源。
协商缓存的 ETag 是怎么生成的
ETag
是对资源的一种标识,通常由服务器根据资源的内容或属性生成。生成方法可以有很多种,具体取决于服务器的实现。
内容哈希: 最常见的方法是对文件内容应用哈希函数(如MD5、SHA-1等),生成一个哈希值。这种方法的优点是只要内容发生改变,生成的
Etag
值就会变,从而确保内容的更新能够被客户端识别。文件属性: 有些实现可能会结合文件的大小、最后修改时间等属性来生成
Etag
。这种方法比内容哈希计算开销小,但可能不如内容哈希精确。自定义规则: 服务器也可以根据自定义规则生成
Etag
,例如结合文件版本号、更新周期等因素。
TCP 握手过程
浏览器发送 TCP 分组,这个分组设置了一个特殊的
SYN
标记,用来表示这是一条连接请求。服务器接受到客户端的
SYN
连接后, 会选择服务器初始序号y
。同时向客户端发送含有连接确认 (SYN + ACK
)、Seq=0
(本例中的服务器初始序号)、ACK=1
(客户端的序号 x + 1) 等信息的 TCP 分组。客户端收到了服务器的确定字段后,向服务器发送带有
ACK=1
、Seq=1
、Ack=1
(服务器 Ack 信息的拷贝)等字段的 TCP 分组给服务器。服务器接收到客户端的确认字段后完成三次握手的连接,开始给客户端传输它想要资源
点击显示真实案例
以下序号
40
、44
、45
为 TCP 三次握手的具体数据信息。在右侧的info
栏中显示了分组的标志位信息: