这是我参与2022首次更文挑战的第4天,活动详情查看:2022首次更文挑战
授课老师:杨超男老师
目录:
- 初识:背景知识;什么是HTTP,其基本特点。
- 协议分析:报文结构,发展历程。
- 常见场景:静态资源、登陆。
- 实际应用:浏览器与node中使用。
- 了解更多:不止HTTP协议一个选择。
01. 初识
日常的HTTP位于哪一部分?
Hyper Text Transfer Protocol:超文本传输协议
应用层协议:基于TCP协议
请求 响应:每一个都有请求和响应两部分。
简单可扩展:可以自定义请求头。
无状态:每一个请求之间都是孤立的。
02. 协议分析
HTTP的发展历程
逐步丰富了HTTP协议的语义,优化了连接的表现。1.1是公认的标准化版本。HTTP/2实现更加快速的传输。
报文分析
以HTTP/1.1 为例,常见的格式如下:
Request的各个Method如下:
除了语义之外,还有特点:
- Safe (安全的) :不会修改服务器的数据的方法
- GET
- HEAD
- OPTIONS
- Idempotent (幂等) :同样的请求被执行一次与连续执行多次的效果是一样的,服务器的状态也是一样的。所有safe的方法都是ldempotent的。
- GET
- HEAD
- OPTIONS
- PUT
- DELETE
状态码
常见状态码如下:
- 200 OK-客户端请求成功
- 301 -资源(网页等)被永久转移到其它URL
- 302 -临时跳转
- 401 Unauthorized -请求未经授权
- 404 -请求资源不存在,可能是输入了错误的URL
- 500 -服务器内部发生了不可预期的错误
- 504 GatewayTimeout-网关或者代理的服务器无法在规 定的时间内获得想要的响应。
RESTful API
一种AP|设计风格 REST - Representational State Transfer
(1)每一个URI代表一种资源; (2)客户端和服务器之间,传递这种资源的某种表现层; (3)客户端通过HTTP method,对服务器端资源进行操作,实现"表现层状态转化"。
常用请求头
Origin可以表明从哪里发送的,比如安卓 Cookie可以表示登录状态
常用响应头
access-control-allow-origin:*:允许所有域名访问
缓存: 强缓存 + 协商缓存 强缓存
- Expires ,时间戳
- Cache-Control
- 可缓存性
- no-cache:协商缓存验证
- no-store:不使用任何缓存
- public /private
- 到期
- max-age:单位是秒,存储的最大周期,相对于请求的时间(相对时间)
- 重新验证*重新加载
- must-revalidate:一旦资源过期,在成功向原始服务器验证之前,不能使用 (一般和max-age搭配使用。场景:若浏览器与服务器断开连接后,如果没有设置must-revalidate,那么可以继续使用,如果设置了这个属性,那么久必须等到重连服务器才行。)
- 可缓存性
协商缓存
- Etag/If-None-Match :资源的特定版本的标识符,类似于指纹
- Last-Modified/If-Modified-Since :最后修改时间(绝对时间)
Last-Modified位于响应里面,If-Modified-Since位于请求里面。
问:是否存在优先级? 答: √。
强缓存 --> ETag --> Last-Modified
强缓存直接读,而后面两步会返回304。
cookie
secure和HttpOnly都是为了加强cookie的安全性的。 SameSite主要是防范跨站攻击的一个有效手段。
HTTP/2概述
HTTP/2概述:更快、更稳定、更简单
- 帧(frame) : HTTP/2通信的最小单位,每个帧都包含帧头,至少也会标识出当前帧所属的数据流。
※ 使用二进制编码替代纯文本,同时增加了一些压缩算法。
- 消息:与逻辑请求或响应消息对应的完整的一系列帧。
- 数据流:已建立的连接内的双向字节流,可以承载一条或多条消息。
※ 交错发送,接收方重组织
比如拆成了5个帧,再利用每个帧的起点,拼接。
- HTTP/2连接都是永久的,而且仅需要每个来源一个连接。
- 流控制:阻止发送方向接收方发送大量数据的机制。
- 服务器推送:若在html里面检测到js和css文件,则可以提前推送文件。(少见,得不偿失)
比如传输一个视频,如果用户暂停,那么可以暂停传输。
HTTPS概述
HTTPS : Hypertext Transfer Protocol Secure 经过TSL/SSL加密
对称加密:加密和解密都是使用同一个密钥 非对称加密,加密和解密需要使用两个不同的密钥: 公钥(public key) 和 私钥(private key)
请求流程:
HTTP与HTTPS的对比:(其实多了一层加密啦~)
03. 场景分析
静态资源
打开任意网址--控制台--右键检查(F12)--Network
- CSS
Status Code:200.
刷新页面后再次加载,会出现
(from disk cache)
问题:状态码200,一定是发起了请求吗?
回答:显然,用的强缓存。请求头:Cache-control:max-age=31536000
静态资源如何部署?
方案:缓存 + CDN + 文件名hash
CDN : Content Delivery Network
- 通过用户就近性和服务器负载的判断,CDN确保内容以一种极为高效的方式为用户的请求提供服务。
为什么需要给文件名加hash值:因为强缓存的时间如果过长,那么用户无法及时更新对应的文件,比如xxx.css。
登录
- 业务场景
- 表单登录
- 扫码登录
- 技术方式
- SS0:单点登录(Single Sign On)
网址登录后,查找控制台中的login请求。为什么会出现两个请求呢? 回答:其中一个是预请求。另一个是正常请求,XHR(XMLHttpRequest)
从一个请求开始分析:会注意到其中的options请求。因为存在跨域问题:
toutiao.com ---> sso.toutiao.com
- CORS(Cross-Origin Resource Sharing )
- 预请求:获知服务端是否允许该跨源请求(复杂请求)
- 相关协议头
- Access-Control-Allow-Origin
- Access-Control-Expose-Headers
- Access-Control-Max-Age
- Access-Control-Allow-Credentials
- Access-Control-Allow-Methods
- Access-Control-Allow-Headers
- Access-Control-Request-Method
- Access-Control-Request-Headers
- Origin
如何解决跨域问题?
- 可以使用代理服务器,因为同源策略是浏览器的安全策略,不是HTTP的
- iframe,诸多不便。
如何记住上一次的登录状态?
- 鉴权:Session + Cookie
- JWT: (JSON web token)
为什么点击写文章,跳转到另外一个域名下的网站,会携带我的用户登录状态呢?
SSO:单点登录解决方法。
登录在SSO的server,在A站点下种下cookie,每次查询登录态即可。若要跳转到B,则从B去SSO查询对应的登录态,若登录,则在B站点种下一个cookie。
04. 实战
Ajax之 XHR
XHR:XMLHttpRequest
readState:
封装的函数:
Ajax之 Fetch
- XMLHttpRequet的升级版
- 使用Promise
- 模块化设计,Response,Request,Header对象
- 通过数据流处理对象,支持分块读取
常用的请求库: axios
- 支持浏览器、nodejs环境
- 丰富的拦截器
用户体验:快 & 稳定性
网络优化:
稳定性:
- 重试是保证稳定的有效手段,但要防止加剧恶劣情况。(万一一直失败呢???)
- 缓存合理使用,作为最后一道防线。
05. 了解更多
WebSocket
浏览器与服务器进行全双工通讯的网络技术。(方案)
-
典型场景:实时性要求高,例如聊天室,行情k线。
-
URL使用ws://或wss://等开头
QUIC
QUIC: Quick UDP Internet Connection。一种UDP封装的新版本传输协议。
- 0-RTT建联(首次建联除外)。
- 类似TCP的可靠传输。
- 类似TLS的加密传输,支持完美前向安全。
- 用户空间的拥塞控制,最新的BBR算法。
- 支持h2的基于流的多路复用,但没有TCP的HOL问题。
- 前向纠错FEC。
- 类似MPTCP的Connection migration。
仍然处于草案阶段:
课外疑问
GET 和 POST 有什么区别?
- 从语义上讲:
- GET - 从指定的资源请求数据(读操作)。
- POST - 向指定的资源提交要被处理的数据(写操作)。 (当然,你要是混用也可以。)
- 实际不同点:
| GET | POST | |
|---|---|---|
| 后退按钮/刷新 | 无害 | 数据会被重新提交(浏览器应该告知用户数据会被重新提交)。 |
| 缓存 | 能被缓存 | 不能缓存 |
| 编码类型 | application/x-www-form-urlencoded | application/x-www-form-urlencoded or multipart/form-data。为二进制数据使用多重编码。 |
| 历史 | 参数保留在浏览器历史中。 | 参数不会保存在浏览器历史中。 |
| 对数据长度的限制 | 是的。当发送数据时,GET 方法向 URL 添加数据;URL 的长度是受限制的(URL 的最大长度是 2048 个字符)。 | 无限制。 |
| 对数据类型的限制 | 只允许 ASCII 字符。 | 没有限制。也允许二进制数据。 |
| 安全性 | 与 POST 相比,GET 的安全性较差,因为所发送的数据是 URL 的一部分。 在发送密码或其他敏感信息时绝不要使用 GET ! | POST 比 GET 更安全,因为参数不会被保存在浏览器历史或 web 服务器日志中。 |
| 可见性 | 数据在 URL 中对所有人都是可见的。 | 数据不会显示在 URL 中。 |