主要总结自:https://juejin.cn/post/6844904100035821575
2022-9-1 持续更新
本文将从如下几点总结 HTTP 相关知识:
- 状态码
- 请求/响应头
- CORS
- 浏览器请求到渲染的过程
- 缓存
- http/1.0、http/1.1、http/2 相关内容
- GET、POST 的区别
- Cookie、localStorage、sessionStorage 的区别
- HTTP 特点
状态码
- 1xx 服务器收到请求
- 2xx 请求成功
- 3xx 重定向相关
- 301 永久重定向 - 浏览器会自动更新收藏夹
- 302 临时重定向
- 304 未修改 - 实际和重定向无关,和缓存相关
- 4xx 客户端错误
- 401 未认证
- 403 禁止访问
- 404 请求的内容不存在
- 405 请求方法不允许
- 5xx 服务端错误
- 500 服务器错误
- 501 未实现
- 502 网关错误,具体是啥不知道
- 503 服务临时不可用
请求/响应头
HTTP 请求头可谓五花八门,为了实现各种功能有各种不同的字段,下面挑几个比较重要的讲
Accept 相关
- 编码
- 客户端发送 Accept-Charset,服务端在 Content-Type 中返回
- 内容格式
- MIME
- 客户端发送 Content-Type
- 服务端发送 Content-Type
- 语言
- 客户端发送 Accept-Language
- 服务端发送 Content-Language
- 压缩
- 客户端发送 Accept-Encoding
- 服务端发送 Content-Encoding
范围请求
Content-Length 表示请求的内容的长度(单位 bytes),如果资源支持范围请求,服务端需要设置 Accept-Range: none
,然后客户端发送请求得到 Range: 请求的部分
和 206 状态码,表示请求成功。
表单数据
前端常用的 POST 发送数据的格式如下三种:
- application/json
- application/x-www-form-urlencoded
- multipart/form-data
其中 json 格式的数据直接在 axios 传递即可,而 form-urlencoded
的数据需要把对象改成 k-v 对的形式,如 {username: xxx, age: xxx}
-> username=xxx&age=xxx
和 GET 传参方式类似。最后 multipart/form-data
传递的是表单数据,因为 form-urlencoded
会对数据编码,所以在传文件的时候一般用 form-data
。
CORS
先讲解下 URL 的组成:
URL = 协议 + 主机名 + [端口 + 路径 + 查询参数 + 锚点]
其中方括号内的内容在特定情况下可以省略。
跨域就发生在当前网页想访问在不同的协议、主机、端口(任意一个成立即可)的网页时发生,跨域请求的响应会被浏览器拦截,也就是说实际上请求时发送到主机上了的。而如果浏览器判断当前请求发生了跨域且不符合服务器返回的跨域规则,则本次请求的内容会被浏览器丢弃,并且请求会报错。
浏览器在处理请求时,把请求分为了简单请求
和除简单请求外的请求,先讲讲简单请求的定义
请求头只包含:
- Accept
- Accept-Languge
- Content-Type 为
application/x-www-form-urlencoded
或 multipart/form-data
或 text/plain
- 还有一个忘了,但是也是和 Accept 相关
对于简单请求,浏览器在发送请求时,会在请求头附带一个 Origin 字段,该字段的值为当前网站的域名,然后检查服务器的响应头中的 Access-Control-Allow-Origin
字段是否包含当前网站的域名,如果包含,则请求成功,否则报错。此外,Access-Control-*
还包括
Access-Control-Allow-Headers
指示允许客户端携带的额外请求头的字段Access-Control-Allow-Credients
bool 值,表示本次请求是否允许携带 CookieAccess-Control-Max-Age
下次发送预检请求的间隔,在该时间内不会发送预检请求(除简单外需要)- …
除简单请求外,浏览器在处理跨域请求时会先用 OPTIONS
方法预检本次请求是否能够发送,发送预检请求的过程类似简单请求,通过预检请求的服务器响应头判断是否能过跨域,如果能则发送实际请求,否则本次请求出错。常见的 Content-Type: application/json
就会先发送预检。
解决跨域的方法
- jsonp 利用 js 不会跨域的特点注册回调,缺点是只能用于 GET 请求,已经很少使用
- nginx反代 通过反代添加 Access-Control 请求头达到跨域目的
- 后端配置 后端设置允许的域名,从根本解决问题
- webpack、vite 等打包工具的反代
地址栏输入 URL 到浏览器渲染,发生了什么
老八股了,嗯背就完事了
- 浏览器解析 URL,查找本地缓存(见缓存章节)
- 发送 DNS 请求,获取域名 IP。(递归查询、迭代查询)
- 建立 TCP 连接(三次握手)
- 发送 HTTP 报文
- 获取到数据
- 解析 HTML:BYTES -> TEXT -> TOKEN -> NODES -> DOM
- 解析 CSS:BYTES -> TEXT -> TOKEN -> NODE -> CSSOM
- DOM 结合 CSSOM 生成渲染树,只有渲染树中的结点会被显示在页面上,也就是说通过 CSS 设置元素 display: none 的元素不会出现在渲染树上
- 回流,计算元素大小、在页面位置等信息
- 重绘,显示元素
缓存
意义:减少请求时间,提升用户体验。
浏览器缓存策略分为两种——强缓存和协商缓存,在强缓存失效的情况下,会使用协商缓存,如果协商缓存也失效,则重新发起请求并更新缓存数据,下面分别介绍这两种缓存。
强缓存
- 强缓存一般存在本地磁盘、内存中
- 如果强缓存没失效,则直接使用
强缓存由两个服务器响应字段控制 - expires http/1.0 提出,内容为一个 GMT 字符串,表示缓存的过期时间。缺点是因为是绝对时间,所以和客户端时间有关,但是兼容性好。
- cache-control http/1.1 提出,常用选项如下
- max-age 同样是缓存过期时间,但是单位是秒,过了 n 秒后缓存失效,和客户端时间无关
- no-store 使用强缓存,但是客户端每次需要向服务端确认缓存是否过期
- public/privte 代理服务器是否能缓存数据,对于一些敏感信息不应该让代理服务器缓存
协商缓存
强缓存失效后,走协商缓存。协商缓存由客户端和服务端的请求头的几个字段控制,浏览器会发送请求,由服务器判断缓存是否过期,如果过期返回 200 和新数据,否则直接返回 304 表示协商缓存未失效。
服务端
- Last-Modify 指示文件最后的修改/查看时间,配合客户端的 Last-Modify-Since
- ETag 文件的唯一标识符(hash),配合客户端的 If-None-Match,能过避免因为查看文件实际并没修改文件导致 Last-Modify 更新的问题
客户端
- Last-Modify-Since 由 Last-Modify 设置,如果服务端的文件没被更改(Last-Modify-Since == Last-Modify)则返回 304 表示协商缓存生效
- If-None-Match 由 ETag 设置,如果客户端的值和服务端的值相同,表示文件未被更改,304 协商缓存生效
http/1.0、http/1.1、http/2 相关内容
http/1.0
无长链接,每次发请求都需要重新握手,导致性能低下。存在队头堵塞问题,因为 HTTP 基于请求-应答
模式,前一个请求如果很耗时就会导致后一个请求等待时间过长。
http/1.1
默认长连接,通过 keep-alive
字段设置。解决队头堵塞的方法:
- 多并发请求 - chrome 对一个网页能有 6 个并发请求
- 设置多个域名 - 提高并发请求的量
http/2.0
相对于 http/1 版本,主要优化有:
- 请求头压缩 - 在服务端和客户端建立一个 hash 表,把常用的请求头用下标代替
- 多路复用 -
- 服务端推送 - 服务器可以主动推送数据给客户端
GET 和 POST 的区别
- 语义区别
- 传参方式 - GET 明文传参,不安全
- 幂等性 - GET 是幂等的
- 缓存 - GET 请求的内容会被保存到历史记录,同时有缓存
- 传参的大小 - GET 传参的字符串有大小限制
Cookie、localStorage、sessionStorage 的区别
Cookie
- 一串文本,最大不能超过 4KB
- 会随着 HTTP 请求一同发送,能弥补 HTTP 无状态的缺点,可以通过服务器响应头设置发送的域名
- 因为会随着 HTTP 请求发送,所以会导致请求变慢
- 操作方法简陋,只有一个 document.cookie 提供了查看功能
- Cookie 安全相关 - 由服务器设置
- secure 设置后仅在 HTTPS 请求中发送
- httponly 设置后无法通过 document.cookie 查到,能避免 CSRF 攻击
- Same-Site:取值为 strict、lax、none,分别表示仅同源附加 cookie、部分非同源请求能附加 cookie、无同源限制
- 设置 Domain、Path 附加 cookie 的 URL
localStorage
- HTML5 提出的 webStorage 的内容
- 信息永久存储,最大 5MB
- 和 cookie 不同,不会随请求发送
- 仅能同站访问
sessionStorage
基本同 localStorage,但是浏览器关闭后内容会被清空。
HTTP 的特点
优点
- 可靠传输 - 底层是 TCP
- 无状态
- 请求-应答 方式
- 简单
缺点
- 明文传输
- 无状态
- 有队头堵塞问题