定义
HTTP(HyperText Transfer Protocol,超文本传输协议)端与端之间的通讯协议 ,这种协议限制了通讯 💁内容的格式 以及各项 💁内容的含义
👉网络协议分层
- 低三层(了解)
- 物理层:定义物理设备(硬件设备)如何传输数据
- 数据链路层:在通信的实体间建立数据链路连接(0,1数据)
- 网络层:为数据在结点间传输创建逻辑链路
- 传输层
tcp协议在传输层- 向用户提供可靠的端到端
End-to-End服务 - 传输层向高层屏蔽了下层数据通信的细节
- 应用层
http协议在应用层- 为应用软件提供了很多服务
- 构建与
TCP协议之上 - 屏蔽网络传输相关细节
👉应用软件架构
B/S架构Browser(浏览器) ←→Server(服务器)- 这种软件都是通过浏览器访问一个网站使用, 服务器提供数据存储等服务
C/S架构Client(客户端) ←→Server(服务器)- 这种软件通过安装一个软件到电脑,然后使用, 服务器提供数据存储等服务
http历史版本
👉HTTP/0.9
- 只有一个命令
get - 没有
header等描述数据的信息 - 服务器发送完毕,就关闭
tcp连接
👉HTTP/1.0(几乎和1.1差不多)
- 增加了更多命令
post,put,header等 - 增加了状态码(描述服务端处理请求的状态),
header(请求数据的描述)等
👉HTTP/1.1(在1.0上增加了功能来优化网络链接的过程)
- 持久连接/长链接
keep-alive(默认开启)tcp3次握手连接消耗比较大,延时也会较多
pipeline并行管道化(服务端大多不支持,默认不开启)- 增加
host等http头和其他命令host可以允许一台机器上有几个服务,通过host确定连接哪个
💜 持久连接/http长连接Connection:keep-alive
-
1.1版本才支持,1.0版本不支持
-
1.1版本默认打开
Connection:Keep-alive -
ConnectionKeep-aliveclose(不开启长连接,每次请求完则关闭这个tcp连接)
-
http协议采用“请求-应答”模式,当使用普通模式,即非Keep-Alive模式时,每个请求/应答客户和客户端和服务器都要新建一个连接,完成之后立即断开连接(http为无连接的协议) -
当使用
Keep-Alive模式(持久连接,连接重用)时,Keep-Alive功能使客户端到服务器端的连接持续有效,当出现对服务端的后继请求时,Keep-Alive功能避免了重新建立连接 -
优点:每一次建立连接过程,有
TCP三次握手,消耗和延时都比较高
💜 管线化pipeline
-
管线化原理
- 在持久连接的情况下,某个连接上的传递类似于
请求1->响应1->请求2->响应2->请求3->响应3(整个连接无中断,一次请求对应一次响应) - 管线化即在持久连接的基础上消息变成了
请求1->请求2->请求3->响应1->响应2->响应3(多次请求打包一次传给服务器,服务器也一次打包全响应回来) - 由串行变成了并行
- 在持久连接的情况下,某个连接上的传递类似于
-
管线化的特点
- 管线化机制通过持久连接完成,仅
HTTP/1.1支持此技术 - 只有
GET和HEAD请求可以进行管线化,POST有限制 - 初次创建连接时不应该启动管线化机制,因为服务器不一定支持
HTTP/1.1版本的协议 HTTP/1.1要求服务器支持管线化,并不要求服务器对响应进行管线化处理,知识要求管线化请求不失败即可- 由于上面提到的服务器端的问题,开启管线化很可能不会带来大幅度的性能提升,而且很多服务器端和代理程序对管线化的支持并不好,因此
Chrome和Firefox默认并未开启管线化支持
- 管线化机制通过持久连接完成,仅
👉HTTP/2.0(为了解决HTTP/1.1性能低下问题,目前还未普及)
- 二进制传输(之前是字符串)
- 信道复用,并行传输(类似
pipeline)- 同一连接里发送多个请求不再需要按照顺序来(并发请求),不会阻塞,
HTTP/1.1里同一连接里需要第一个发送完才能发送第二个,不能并发。
- 同一连接里发送多个请求不再需要按照顺序来(并发请求),不会阻塞,
- 头信息压缩(减少带宽使用)
- 推送(之前只有客户端能发起请求,服务端不能主动传输)
- 例如请求一个
html页面,如果里面包含有css,js文件,HTTP/1.1中是需要先请求到页面,再请求里面的css,js,是串行的。而HTTP/2.0是请求页面的同时,服务器将页面包含的css,js等一起推送到客户端
- 例如请求一个
- 不是所有浏览器都支持
HTTP/2.0Nginx可以做兼容,服务器端可以直接用HTTP/1.1,Nginx代理服务器可以转换为HTTP/2.0
http协议的主要特点
- 简单快速
- 每个资源的
URI是固定的,输入该URI就能访问
- 每个资源的
- 灵活
http协议头部可以设置不同数据类型的传输
- 无连接
- 服务器发送完响应,就关闭
TCP连接(每次连接后会断掉,不会一直保持连接)
- 服务器发送完响应,就关闭
- 无状态
- 客户端和服务端建立一次连接后,这个连接会断开,下次再来连接,服务器是无法记住状态的,无法确认
请求响应流程
请求响应流程图👇
ip 地址用来定位计算机,端口号用来定位具体的应用程序,所有需要联网通信的应用程序都会占用一个端口号(0-65536)
http协议约定形式
- 🚩 客户端通过随机端口与服务端某固定端口建立连接 三次握手
http一般为80,https一般为443
- 🚩 客户端通过这个连接发送请求到服务端(这里的请求是名词)
- 🚩 服务端监听端口得到的客户端发送过来的请求
- 🚩 服务端通过连接响应给客户端状态和内容 (响应报文)
http协议约定内容
- 🚩 请求/响应报文格式
- 🚩 请求方法➡️
GET/POST - 🚩 响应状态➡️
200/302/304/403/404/500 - 🚩 预设的请求头/响应头
👉常用状态码含义
定义服务器对请求的处理结果
-
各个区间的
CODE有各自的语义💁
1xx: 指示信息💁
2xx: 成功,请求已成功接收💁
3xx:需要重定向去获取数据💁
4xx:客户端错误,请求有语法错误或请求无法实现💁
5xx:服务器错误,服务器未能实现合法的请求 -
详细
💚
200 OK- 客户端请求成功
💚
206 Partial Content- 客户端发送了一个带有
Range头的GET请求,服务器完成请求后从文件中截取这个范围内的数据返回(<video><audio>标签请求视频/音频时当文件很大时会出现)
💚
301 Moved Permanently永久重定向- 浏览器访问一次后,下一次不需要服务器继续指定,浏览器直接会直接从缓存里读取,然后访问'/new'页面。无论服务器怎么改,只要客户端不清缓存,这种修改都是无法成功的
💚
302 Found- 请求的资源临时从不同的
URI响应请求。后面浏览器每次访问,都会访问服务器,确认跳转到哪里。只有在Cache-Control或 Expires中进行了指定的情况下,这个响应才是可缓存的
💚
304 Not Modified- 没有改变,走缓存
- 客户端有缓存,服务端告诉客户端可以直接从原来的缓存中取数据。如果客户端发送了一个带条件的
GET请求且该请求已被允许,而文档的内容(自上次访问以来或者根据请求的条件)并没有改变,则服务器应当返回这个状态码。304响应禁止包含消息体,因此始终以消息头后的第一个空行结尾
👿
400 Bad Request- 客户端请求有语法错误(参数格式错误等),不能被服务器所理解
👿
401 Unauthorized- 请求未经授权,这个状态代码必须和 WWW-Authenticate 报头域一起使用
👿
403 Forbidden- 资源禁止被访问,服务器已经理解请求,但是拒绝执行它
👿
404 Not Found- 请求失败,请求资源不存在 ,请求所希望得到的资源未被在服务器上发现,可能是输入了错误的URL
👿
500 Internal Server Error- 服务器遇到了一个未曾预料的状况,导致了它无法完成对请求的处理。一般来说,这个问题都会在服务器端的源代码出现错误时出现
👿
503 Server Unavailable- 服务器临时过载或宕机,暂时不能处理客户端的请求,一段时间后可能恢复正常
💜 重定向redirect
response.writeHead(302, {
'Location': '/new'
})
// 浏览器识别到302,就直接跳转到Location的位置,但是如果返回的code是200,不会跳转
301和302的区别301:浏览器访问一次后,下一次不需要服务器继续指定,浏览器直接会直接从缓存里读取,然后访问/new页面。无论服务器怎么改,只要客户端不清缓存,这种修改都是无法成功的302:浏览器每次访问,都会访问服务器,确认跳转到哪里
👉http报文组成部分
💜请求报文格式
🙉 请求行
GET /demo.php HTTP/1.1- 请求方式+空格+请求路径+空格+HTTP协议版本
🙉 请求头
- 客户端想要告诉服务端的一些额外信息,键值对形式
- 常见的如下 键 | 值 | | --------------- | --------------------------- | | Host | 请求的主机 | | Cache-Control | 控制缓存(例如:max-age=60 缓存 60 秒) | | Accept | 客户端想要接收的文档类型,逗号分隔 | | User-Agent | 标识什么客户端帮你发送的这次请求 | | Referer | 这次请求的来源 | | Accept-Encoding | 可以接受的压缩编码 | | Cookie | 客户端本地的小票信息 | | Connection | keep-alive |
🙉 空行
- 格式而已
🙉 请求体
- 这次请求客户端想要发送给服务端的数据正文(参数),一般在 GET 请求时很少用到,因为 GET 请求主观上都是去“拿东西”
💜 响应报文格式
🙉 状态行
HTTP/1.1 200 OK- HTTP 协议版本 + 空格 + 状态码 + 空格 + 状态描述
🙉 响应头
- 服务端想要告诉客户端的一些额外信息
| 键 | 值 |
|---|---|
| Date | 响应时间 |
| Server | 服务器信息 |
| Content-Type | 响应体的内容类型 |
| Content-Length | 响应的内容大小 |
| Set-Cookie | 让客户端设置一个小票 |
| Location | 重定向的地址(302) |
| Cache-Control | 设置是否缓存 |
🙉 空行
- 仅格式
🙉 响应体
- 这次请求服务端想要返回给客户端的数据正文,一般返回的都是 HTML,也可以返回 JavaScript 或者 CSS(需要修改响应头中的响应类型)
💜 请求头/响应头参数作用
🙉Content-Type
值为
HTTP MIME type,用于指示资源的MIME类型 tool.oschina.net/commons
-
纯字符串:
text/plain -
html:
text/html(默认值) -
css:
text/css -
js:
application/javascript,text/javascript -
json:
application/json请求接口返回的格式 -
浏览器的原生
form表单:application/x-www-form-urlencoded。提交的数据按照key1=val1&key2=val2的方式进行编码,key和val都进行了URL转码 -
jpg的图:
image/jpg图片就不需要指定编码了,因为我们常说的编码一般指的是:字符编码 -
上传文件:
multipart/form-data。常见的POST数据提交的方式。我们使用表单上传文件时,必须让form的enctype等于这个值。 -
让文件下载:
application/octet‐stream// 当浏览器无法识别该扩展名时,默认会下载下来,除此之外,想要下载,则要做如下处理 // 让文件下载 header('Content‐Type: application/octet‐stream'); // 设置默认下载文件名 header('Content‐Disposition: attachment; filename=demo.txt'); -
如果需要设置编码类型,在后面加(
;charset=GBK或;charset=UTF-8)
🙉 Location
重定向到另一个地址
🙉 Referer
图片防盗链。通过判断请求来源
Referer是否为本网站从而区分是否是合法请求
🙉 数据协商
- 请求头
AcceptAccept-EncodingAccept-LanguageUser-Agent
- 响应头
Content-Type对应AcceptContent-EncodingContent-Language
💜 缓存
🙉 Cache-Control
例子
'Cache-Control':'max-age=200, public'
-
可缓存性
-
public(强制缓存)- http请求返回过程中,所经过的所有路径,包括经过的所有代理服务器,和发起请求的浏览器也可以缓存
-
private(强制缓存)- 仅发送请求的浏览器可以缓存
-
no-cache(协商缓存)- 本地和代理服务器可以存缓存,但是要服务器协商缓存告诉可以使用缓存才能使用
-
no-store(不缓存) -
强制缓存的弊端很明显,当缓存过期后,一定会重新去服务器再次请求(不管数据是否有改动),如果数据没有改动,会浪费服务器资源,因此会用到协商缓存
-
优先级:不缓存 > 强制缓存 > 协商缓存
-
-
到期
-
max-age=[seconds]设置缓存存储的最大周期,超过这个时间缓存被认为过期(单位秒)。与Expires相反,时间是相对于请求的时间。max-age会覆盖掉Expires -
s-maxage=[seconds],针对代理服务器设置,用于代理缓存。如果存在s-maxage,则会覆盖max-age和Expires -
max-stale=[seconds],浏览器端设置,即便缓存max-age过期了,还是拿缓存。客户端愿意接收一个已经过期的资源。 可选的设置一个时间(单位秒),表示响应不能超过的过时时间 -
浏览器端读取
max-age,代理服务器如果设置了s-maxage则读取它
-
-
重新验证
-
must-revalidate- max-age已经过期,必须去原服务端获取数据
-
proxy-revalidate- 用在缓存服务器中,过期时,必须去原服务器获取数据
-
-
其他
-
no-store- 本地和代理服务器都不能存储缓存,禁止缓存
-
no-cache- 本地和代理服务器可以存缓存,但是要服务器验证过告诉可以使用缓存才能使用
-
no-transform- 不得对资源进行转换或转变。
Content-Encoding,Content-Range,Content-Type等http头不能由代理修改。例如,非透明代理可以对图像格式进行转换,以便节省缓存空间或者减少缓慢链路上的流量。no-transform指令不允许这样做。
- 不得对资源进行转换或转变。
-
🙉 资源验证,协商缓存(使用no-cache时需要做的)👇
响应验证头
-
Last-Modified- 上次修改时间
- 配合浏览器请求头
If-Modified-Since(推荐)或者If-Unmodified-Since使用 - 对比上次修改时间验证资源是否需要更新
-
Etag- 数据签名,比
Last-Modified更严格的验证 - 配合浏览器请求头
If-Match或者If-Non-Match使用 - 对比资源的签名判断是否使用缓存
- 数据签名,比
-
如果判断
If-Match和Etag相同,或者If-Modified-Since和Last-Modified相同,则会返回304,不再读取服务器的数据,从缓存取数据即可,当设置no-store时,不会在服务端判断,直接重新读取数据,返回200 -
chrome调试工具里面勾选Disable cache时- 浏览器就不会再发请求头
If-Match和If-Modified-Since了,从而服务端无法判断,无法使用缓存
- 浏览器就不会再发请求头
🙉 expire
HTTP/1.0的内容,是强制缓存,过期时间为绝对时间- 当
cache-control和expire同时存在时,cache-control优先级比较高,无论expire是否过期,都无效
🙉 pragma
HTTP/1.0的内容,和cache-control类似。前者是http1.0内容后者是http1.1内容pragma优先级 >cache-control优先级,不过前者目前基本不使用
http方法
用来定义对资源的操作,定义上有各自语义
get获取资源post传输资源put更新资源delete删除资源head获取报文头部
👉POST和GET的区别
1 GET请求会被浏览器主动缓存,而POST不会
2 GET请求参数会被完整保留在浏览器历史记录里,而POST中参数不会被保留
3 GET请求在URL中传送的参数是有长度限制的,而POST没有限制
4 GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息
| 0 | GET | POST |
|---|---|---|
| 浏览器后退 | 无害 | 请求会被重新提交 |
| url地址收藏为书签 | 可以 | 不可以 |
| 浏览器缓存 | 主动缓存 | 不主动缓存,除非手动设置 |
| 编码类型 | 只支持url编码:application/x-www-form-urlencoded | 支持多种编码方式 |
| 浏览器历史记录 | 参数保存在浏览器历史记录中 | 参数不保留(可防止CRS攻击) |
| 参数长度限制 | GET 方法向 URL 添加数据;URL 的长度是受限制的(URL 的最大长度是 2048 个字符(2kb)),太长会被截断 | 无限制 |
| 参数数据类型限制 | 只接受ASCII字符 | 无限制 |
| 安全性 | 与 POST 相比,GET 的安全性较差,因为所发送的数据是 URL 的一部分。在发送密码或其他敏感信息时绝不要使用 GET | POST 比 GET 更安全,因为参数不会被保存在浏览器历史或 web 服务器日志中 |
| 参数可见性 | url传递,所有人可见 | Request body中,url中看不见 |
http与https的区别
- http是明文传输
- 传输过程中的包被截取后,信息完全泄露
- https是靠谱的加密传输
- 私钥:服务器的私钥解密
- 公钥:互联网上传输的公钥,需要服务器上的私钥来解密
- 实际传输数据只有客户端和服务端通过主密钥来获取到
Cookie与Session
后续补充