HTTP学习笔记 | 青训营
这是我参与「第五届青训营 」伴学笔记创作活动的第 5 天
初识http协议
HTTP协议(Hyper Text Transfer Protocol)超文本传输协议
- 一个基于应用层的TCP协议
能够承载HTML,CSS,JS和WEB API。
- 有请求和响应两种功能。
- 简单可拓展:
在HTTP请求中,能够自定义header的属性,但是client
和server
要能够对自定义的属性进行处理。 - 无状态
每个请求之间都是没有关系的。当前请求与之前请求都没有关系。
协议发展
最初设计是为了client和server进行通信。
- HTTP/0.9
单行协议。只有get方法和目标地址。响应只能承载HTML文档。
- HTTP/1.0
构建可拓展性。增加了Header,状态码,支持多种文档类型:CSS,HTML,JS等。
- HTTP/1.1
标准化协议。使用时间最长的版本。由于基于TCP,为了让HTTP协议有更好的表现,增加了链接复用,缓存,内容协商等功能。
- HTTP/2
优异的表现。二进制协议,压缩Header,服务器推送。
- HTTP/3
草案 还没实施
协议分析-报文
以HTTP1.1为例
在图中,req和res都有一个首行标注协议信息。res还会返回一个处理结果的状态码
Version StatusCode StatusMessage
有一个Header区域,它们之间有一部分语义是一样的,有一部分是res或者req特有的语义。
最后部分是信息区域。返回或者传递一个需要传输的信息。
HTTP方法
Method | |
---|---|
GET | 请求一个指定资源的表示形式 使用GET的请求应该只被用户获取数据 |
POST | 用于将实体提交到指定的资源,通常导致在服务器上的状态变化或副作用 |
PUT | 用请求有效载荷替换目标资源的所有当前表示 |
DELETE | 删除指定的资源 |
HEAD | 使用较少,请求一个与GET请求的响应相同的响应,但没有响应体 |
CONNECT | 使用较少,建立一个到由目标资源标识的服务器的隧道。 |
OPTIONS | 通信时使用,用于描述目标资源的通信选项。 |
TRACE | 沿着到目标资源的路径执行一个消息环回测试 |
PATCH | 用于对资源应用部分修改 |
安全的请求Safe: 不会修改服务器数据的方法 如: GET HEAD OPTIONS
幂等Idempotent:同样的请求被执行一次与连续执行多次效果相同,服务器状态一致。所有safe方法都是Idempotent的。
如: GET HEAD OPTIONS PUT DELETE
状态码
状态码 | |
---|---|
1xx | 指示信息,表示请求已接收继续处理 |
2xx | 成功,表示请求已被成功接收 |
3xx | 重定向,要完成请求必须进行更进一步的操作 |
4xx | 客户端错误,请求有语法错误或请求无法实现 |
5xx | 服务器端错误,服务器未能实现合法的请求 |
200 OK -----------------> 客户端请求成功
301 --------------------->资源(网页等)被永转移到其它 URL
302 --------------------->临时跳转
401 Unauthorized ----->请求未经授权,不合法
404 ---------------------> 请求资源不存在,可能是输入了错误的 URL
500----------------------> 服务器内部发生了不可预期的错误
504 Gateway Timeout-->网关或者代理的服务器无法在规定的时间内获得想要的响应
RESTFUL API
一种API设计风格,REST-表现层状态转换( ),
每一种URL代表一种资源
客户端和服务器之间传递这种资源的某种表现层
客户端通过HTTP method对服务器端的资源进行操作,实现表现层状态转化
客户端连接服务端数据库常用的形式。
形如:GET /admin/login | 返回状态码: 200: OK 402: 失败
个人理解:或许是用来在连接接口返回状态时候使用的状态码
常用请求头
常用请求头 | |
---|---|
Accept | 接收类型,表示浏览器支持的MIME类型 (对标服务端返回的Content-Type) |
Content-Type | 客户端发送出去实体内容的类型,比如传递表单,可以用formdata也可以用json |
Cache-Control | 指定请求和响应遵循的缓存机制,如no-cache |
If-Modified-Since | 对应服务端的Last-Modified,用来匹配看文件是否变动,只能精确到1s之内 |
Expires | 缓存控制,在这个时间内不会请求,直接使用缓存,服务端时间 |
Max-age | 代表资源在本地缓存多少秒,有效时间内不会请求,而是使用缓存 |
If-None-Match | 对应服务端的ETag,用来匹配文件内容是否改变 (非常精确) |
Cookie | 有cookie并目同域访问时会自动带上 |
Referer | 该页面的来源URL(适用千所有类型的请求,会精确到详细页面地址,csrf拦截常 用到这个字段) |
Origin | 最初的请求是从哪里发起的 (只会精确到端口),Origin比Referer更尊重隐私 |
User-Agent | 用户客户端的一些必要信息,如UA头部等,标注客户端时IOS还是windwow |
有时候在爬取需要的信息或者测试网站状态用的上
常用响应头
常用响应头 | |
---|---|
Content-Type | 服务端返回的实体内容的类型 |
Cache-Control | 指定请求和响应道循的缓存机制,如no-cache |
Last-Modified | 请求资源的最后修改时间 |
Expires | 应该在什么时候认为文档已经过期,从而不再缓存它 |
Max-age | 客户端的本地资源应该缓存多少秒,开启了Cache-Control后有效 |
ETag | 资源的特定版本的标识符,Etgs类似于指纹 |
Set-Cookie | 设置和页面关联的cookie,服务器通过这个头部把cookie传给客户端 |
Server | 服务器的一些相关信息 |
Access-Control-Allow-Origin | 服务器端允许的请求Origin头部 (警如为*) |
有时候在爬取需要的信息或者测试网站状态用的上
缓存
- 强缓存
本地有的直接用
- 协商缓存
本地有但是可能过期。需要访问server端通信确认是否可用。
Etag/if-None-Match 一般采用某种算法进行识别。
优先级的一些问题
首先判断强缓存是否过期,若没有则使用强缓存,否则使用协商缓存。协商缓存要判断Etag,没有Etag则判断Last=Modified。最后根据信息的有无更新缓存并返回到浏览器。
一般用于加快网页加载静态资源
cookie
Set-Cookie - response | |
---|---|
Name=value | 各种cookie的名称和值 |
Expires=Date | Cookie 的有效期,缺省时Cookie仅在浏览器关闭之前有效。 |
Path=Path | 限制指定Cookie 的发送范围的文件目录,默认为当前 |
Domain=domain | 限制cookie生效的域名,默认为创建cookie的服务域名 |
secure | 仅在HTTPS 安全连接时,才可以发送Cookie |
HttpOnly | JavaScript 脚本无法获得Cookie |
SameSite=INonelStrictlLax] | 1.None 同站、跨站请求都可发送 2. Strict 仅在同站发送 3. 允许与顶级导航一起发送,并将与第三方网站发起的GET请求一起发送 |
其中secure 和 HttpOnly是与安全有关的。
用于做身份验证 或者 定时刷新?
协议分析-发展
HTTP/2为例
更快,更稳定
帧(frame)是HTTP/2通信的最小的单位。每个帧至少有帧头或者body。帧用二进制编码传输。
消息和数据流
逻辑上能跟请求和响应的帧聚集在一起就是消息。
HTTP建立连接之后后若干条双向字节流。每个字节流上承载一条或者多条消息。
例如:一条res消息可能由2个帧构成,其中一个是header头部,还有一个是body存储Data Frame
数据流钟帧不需要串行执行。
- 每一个目标地址建立链接后,链接被永久利用。
- HTTP/2能够(通过浏览器)控制服务器阻止给你发送大量数据。
- 服务器推送
浏览器请求html文件,服务器推送html文件并解析到还需要传输css和js文件。,此时,他将主动传输这两个文件到浏览器。这就是服务器推送。
HTTPS
在HTTP基础上,添加了数据加密。增加了安全性。
对称加密和非对称加密
服务器客户端和同一个密钥进行加密就是对称加密
用不同的密钥就是非对称加密
HTTPS是两者混用的方法。
数据传输过程:
一些机构颁发证书。在传输过程中,浏览器会判断证书是否合法。不合法会产生警告。合法生成随机数,然后使用随机数进行传输。
服务器通过私钥解密。从而获得数据。
静态资源
静态资源方案: 缓存 + CDN + 文件名hash
当本地有资源的时候,就使用本地资源。
当第一次加载时,可以使用CDN的方法下载资源。加快浏览器打开速度。
在国内几个地区设置CDN节点。申请资源靠近哪个节点就从哪个节点下载资源。一定程度上加快了网页的加载速度。
若近的节点没有内容,那么也能够一步步回源获得资源。
当服务器端更新的时候,使用hash的方式为文件名命名。浏览器找不到资源,从cdn下载。保证资源的更新。
跨域
域由scheme、host name、 port
三部分组成。
scheme 表示协议是https还是http,
host name是域名如:www.baidu.com
port代表端口号
三部分有任意一部分有区别就是跨域。
注意:没有端口号也是同域。
CORS( ) 存在跨域请求。先发起预请求。(复杂请求才会发预请求。):通知服务端是否允许跨源请求。
跨域的解决方案
- 代理服务器
同源策略是浏览器的安全策略,不是HTTP的
通过部署一个代理服务器,每次请求请求同域代理服务器。代理服务器做结果转发到服务器。
webpack 插件ideserver就是一个代理服务器功能。用于调试
- Iframe通信
限制很多,用的较少
鉴权
- cookie + session
发起提交请求,将信息提交到server。
server若是正确的,生成一个session并存储,再通过res和cookie插入到域名和地址下面
下一次访问会将放进去的cookie携带出来。通过跟本地的用户比较和解析就能识别身份。
- jwt(json web token)
提交后,server生成token,本地不存储,直接通过res返回给浏览器。
浏览器下次请求会将token通过req发送到server。server解析token信息。然后返回信息。
短时间用 jwt,如首次注册或是找回密码的邮箱邮件。
SSO 单点登录 single sign on的方案
浏览器
AJAX 与 XHR(XHTMLHttpRequest)
readyState
readyState | ||
---|---|---|
0 | UNSENT | 代理被创建,但尚未调用open() 方法。 |
1 | OPENED | open() 方法已经被调用 |
2 | HEADERS_RECEIVED | send() 方法已经被调用并且头部和状态已经可获得。 |
3 | LOADING | 下载中,responseText 届性已经包含部分数据 |
4 | DONE | 下载操作已完成 |
var xhr = new XMLHttpRequest()
xhr.responseType = option.responseType || 'json'
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
if (option.success && typeof option.success === 'function') {
option.success(xhr.response)
}
} else {
if (option.error && typeof option.error === 'function') {
option.error()
}
}
}
}
这一部分不太明白,抽个时间仔细学一下
AJAX 与 Fetch
- XMLHttpRequest的升级
- 使用Promise
- 模块化设计,Response, Request, Header对象
- 通过是拘留处理对象,支持分块读取
function posData(url, data) {
return fetch(url, {
body: JSON.stringify(data),
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
credentials: 'same-origin', // include, same-origin, *omit
headers: {}, // header 信息
method: 'POST', // *GET,POST,PUT,DELETE,etc.
mode: 'cors', //no-cors, cors, *same-origin
redirect: 'follow', // manual, *follow, error
referrer: 'no-referrer' // *client,no-referrer
})
.then(response => response.json()) // 转化为JSON
}
主要是return中的信息设置
node
axios
支持浏览器和node.js环境,有丰富的拦截器。在课程设计中使用过,算是比较熟悉并好用的工具。在项目中一般都会进行封装。
网络优化
cdn加速和Http/2,域名收敛和发散。数据压缩(gzip,brotil),HTTPS性能优化。
稳定性
重试机制,注意适当使用。可能会崩坏应用。
结语:
这节课的知识有很多,对于初学者的我还需要花时间慢慢消化。由于时间和精力有限,有一些地方没有来得及仔细的记录。因此,本文最终的作用是简单回顾。后续若是继续深入学习再回来慢慢的修改与调优。
引用参考:
初识 HTTP 协议 - 掘金 (juejin.cn)
HTTP 协议的应用场景分析 - 掘金 (juejin.cn)
HTTP 协议实战分析 - 掘金 (juejin.cn)