Loading... # Http 协议的基本认识 ## URI 和 URL 的关系 > URI = Universal Resource Identifier 统一资源标志符(某个人) > URL = Universal Resource Locator 统一资源定位符(这个人的地址) > URN = Universal Resource Name 统一资源名称(这个人的身份证) > URL 的基本格式: `<schemem>://<user>:<password>@<host>:<port>/<path>?<query>#<frag>` ![](https://gz-blog-storage-1252787757.cos.ap-guangzhou.myqcloud.com/usr/uploads/2024/05/17162849316985.jpg) ## HTTP 协议的三个特征 > 1) 持久连接:以前的 http 通信都是完成后断开连接的,下一次重新连接,如果资源不多的情况下,并不会造成什么问题。 > 2) 但是随着 http 的普及,越来越多的资源需要加载,一个 html 可能有 css 、js 等文件,如果还是这样操作,会造成巨大的通信开销。 > 3) 为了解决这个问题,出现了持久连接,只要通信两端没有一端提出断开,就保持连接,下次通信复用这个链接。 > 4) 管道化:过去客户端发送请求,要服务端返回响应才继续下一个请求。 > 5) 启用管道化后,就会将队列迁移到服务器,这样客户端就可以同时发送多个请求,然后等服务器一个接一个响应。 > 6) 状态管理:http 是一种无状态协议,请求和响应一一对应,不会出现两个请求复用一个响应的情况,每个请求都是独立的。 > 7) 有些业务场景需要有状态,比如登录,为了管理状态,引用了 cookie 技术,cookie 能让请求和响应的报文都附加 cookie 信息,那个之间就有一个状态了。 ## HTTP Content ### 1) Request Info ```yaml <Method><Request URL><Version> <Headers> <Body> # Example GET /books/?s=http&action= HTTP/1.1 <Headers> <Body> ``` ### 2) Response Info ```yaml <Version><Status Code><Reason Phrase> <Headers> <Body> # Example HTTP/1.1 200 OK <Headers> <Body> ``` ### 3) Request Methods | 方法 | 功能 | | ------ | -------------------------- | | GET | 获取数据 | | POST | 提交数据 | | PUT | 上传文件 | | DELETE | 删除文件 | | HEAD | 获取除了内容以外的资源信息 | ### 5) Http Status Code | 状态码 | 类别 | 原因短语 | | ------ | ---------- | -------------------------------- | | 1xx | 信息 | 请求已被接受,正在处理中 | | 2xx | 成功 | 请求已处理成功 | | 3xx | 重定向 | 客户端需要附加操作才能完成请求 | | 4xx | 客户端错误 | 客户端发起的请求服务器无法处理 | | 4xx | 服务器错误 | 服务器在处理请求时发生错误或异常 | ## HTTP Header ### 1) Request Common Header | key | desc | | ----------------- | --------------------------------------------- | | Connection | 管理持久连接 | | Date | 报文的创建时间,HTTP 协议使用了特殊的日期格式 | | Transfer-Encoding | 传输报文主体时的编码方式,例如分块传输编码 | ```yaml Connection: keep-alive Date: Tue, 11 Jun 2019 16:31:19 GMT Transfer-Encoding: chunked ``` ### 2) Request Custom Header | key | desc | | --------------- | ------------------------------------------------ | | Accept | 可接受的 MIME 类型 ,q 表示权重,用;分割开 | | Accept-Charset | 可接受的字符集 | | Accept-Encoding | 可接受的编码格式,服务器按指定的编码格式压缩数据 | | Accept-Language | 可接受的语种类型 | | Host | 服务器域名和端口 | | Referer | 上一个页面的地址 | | User-Agent | 用户代理信息,例如操作系统,浏览器名称和版本号等 | ```yaml Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3 Accept-Charset:utf-8 Accept-Encoding: gzip, deflate, br Accept-Language: zh-CN,zh;q=0.9 Host: cn.epubee.com Referer: http://cn.epubee.com/books/ User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.80 Safari/537.36 ``` ### 3) Response Header | 首部 | 描述 | | ------------- | ---------------------------------------------- | | Accept-Ranges | 服务器接受的范围类型 | | Server | 服务器软件的名称和版本 | | Age | 响应存在时间,单位为秒,这个首部可能由代理发出 | ```yaml Accept-Ranges: bytes Server: Microsoft-IIS/7.5 Age: 600 ``` | 首部 | 描述 | | ----------------- | -------------------------------------- | | Content-Encodeing | 内容编码,告知客户端用这个编码格式解压 | | Content-Language | 内容语言 | | Content-Length | 内容尺寸,单位是字节 | | Content-Type | 内容的 MIME 类型 | ```yaml Content-Encoding: gzip Content-Language: zh-CN Content-Length: 9191 Content-Type: text/html;charset=utf-8 ``` ## Cache > 缓存的处理过程可以简单分为几步 > > 1) 首先在缓存中搜索指定资源的副本 > 2) 如果命中,对资源副本进行新鲜度检测(是否过期) > 3) 与服务器进行再验证,验证通过,就更新资源副本的新鲜度,再返回副本资源(此时应该是 304 Not Modified),若不通过就返回资源,再将资源的副本放入缓存中 ### 1) 新鲜度检测 > 1) `Expires: Fri,24 Sep 2020 07:0032 GMT`一般时间在每台服务器不能确认,不太建议使用 > 2) `Cache-Control: max-age=315360` 用秒数来计算过期,比较靠谱 | key | desc | | ------------- | ---------------------------------------- | | Cache-Control | 可以设置,no-cache、no-store、max-age | | no-cache | 将资源缓存,但是要与服务器进行新鲜度验证 | | no-store | 禁止资源缓存 | | max-age | 多少秒过后就过期要重新请求 | ![新鲜度验证流程图](https://gz-blog-storage-1252787757.cos.ap-guangzhou.myqcloud.com/usr/uploads/2024/05/17162849317003.jpg) ### 2) 日期对比法进行验证 > 1) response: 有返回 `Last-Modified: Fri, 17 May 2019 14:50:06 GMT` > 2) 当客户端在缓存资源的时候,把 `Last-Modified` 也缓存起来,当对缓存资源副本再验证的时候,请求报文附加 `If-Modified-Since: Fri, 17 May 2019 14:50:06 GMT` 进行日期对比 ![日期对比验证](https://gz-blog-storage-1252787757.cos.ap-guangzhou.myqcloud.com/usr/uploads/2024/05/17162849317017.jpg) ### 3) 实体标记法进行再验证 > 服务器会生成一个标记,该标记会存在实体首部 ETag 中,在响应报文中附加 ETag `ETag: "023e1d0bfcd51:0"` ```yaml HTTP/1.1 304 Not Modified Last-Modified: Fri, 17 May 2019 14:50:06 GMT Accept-Ranges: bytes ETag: "023e1d0bfcd51:0" Server: Microsoft-IIS/7.5 X-Powered-By: ASP.NET Date: Tue, 11 Jun 2019 09:53:16 GMT ``` > 当客户端在缓存资源的时候,把 `ETag: "023e1d0bfcd51:0` 也缓存起来,当检测是否过期的时候向服务器发请求在头部加多一个 `If-None-Match: "023e1d0bfcd51:0"` ```yaml HTTP/1.1 304 Not Modified Last-Modified: Fri, 17 May 2019 14:50:06 GMT Accept-Ranges: bytes ETag: "023e1d0bfcd51:0" Server: Microsoft-IIS/7.5 X-Powered-By: ASP.NET Date: Tue, 11 Jun 2019 09:53:16 GMT GET /books/?s=http&action= HTTP/1.1 Host: cn.epubee.com Connection: keep-alive Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.80 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3 Referer: http://cn.epubee.com/books/ Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9 Cookie: identify=21742230; user_localid=ip_112.96.67.54; identifyusername=; uemail=biyongyao%40qq.com; kindle_email=; leftshow=1 If-None-Match: "023e1d0bfcd51:0" If-Modified-Since: Fri, 17 May 2019 14:50:06 GMT ``` ![ETag验证图](https://gz-blog-storage-1252787757.cos.ap-guangzhou.myqcloud.com/image/2024/20240515_17157656441407.jpg) ``` © Reprint prohibited Support Appreciate the author AliPayWeChat Like If you think my article is useful to you, please feel free to appreciate