这是我参与「第三届青训营 -后端场」笔记创作活动的的第4篇笔记
知识导图
HTTP报文结构
对于 TCP 而言,在传输的时候分为两个部分:TCP头和数据部分。
而 HTTP 类似,也是header + body的结构,具体而言:
起始行 + 头部 + 空行 + 实体
请求报文和响应报文是有一定区别的
起始行
请求报文
GET /home HTTP/1.1
形式:方法 + 路径 + http版本。
响应报文
HTTP/1.1 200 OK
形式:http版本+状态码+原因
在起始行中,每两个部分之间用空格隔开,最后一个部分后面应该接一个换行,严格遵循ABNF语法规范。
头部
空行
很重要,用来区分开头部和实体。
问: 如果说在头部中间故意加一个空行会怎么样?
那么空行后的内容全部被视为实体。
实体
就是具体的数据了,也就是body部分。请求报文对应请求体, 响应报文对应响应体。
HTTP的请求方法
http/1.1规定了以下请求方法(注意,都是大写):
GET: 通常用来获取资源 HEAD: 获取资源的元信息 POST: 提交数据,即上传数据 PUT: 修改数据 DELETE: 删除资源(几乎用不到) CONNECT: 建立连接隧道,用于代理服务器 OPTIONS: 列出可对资源实行的请求方法,用来跨域请求 TRACE: 追踪请求-响应的传输路径
GET和POST的区别
- 从缓存角度,GET 请求会被浏览器主动缓存下来,留下历史记录,而 POST 默认不会。
- 从编码的角度,GET 只能进行 URL 编码,只能接收 ASCII 字符,而 POST 没有限制。
- 从参数的角度,GET 一般放在 URL 中,因此不安全,POST 放在请求体中,更适合传输敏感信息。
- 从幂等性的角度,GET是幂等的,而POST不是。(幂等表示执行相同的操作,结果也是相同的)
- 从TCP的角度,GET 请求会把请求报文一次性发出去,而 POST 会分为两个 TCP 数据包,首先发 header 部分,如果服务器响应 100(continue), 然后发 body 部分。(火狐浏览器除外,它的 POST 请求只发一个 TCP 包)
URI的结构,编码;HTTP状态码
URI URL URN 的关系,1XX,2XX,3XX,4XX,5XX
HTTP特点
-
灵活可扩展,主要体现在两个方面。一个是语义上的自由,只规定了基本格式,比如空格分隔单词,换行分隔字段,其他的各个部分都没有严格的语法限制。另一个是传输形式的多样性,不仅仅可以传输文本,还能传输图片、视频等任意数据,非常方便。
-
可靠传输。HTTP 基于 TCP/IP,因此把这一特性继承了下来。这属于 TCP 的特性,不具体介绍了。
-
请求-应答。也就是一发一收、有来有回, 当然这个请求方和应答方不单单指客户端和服务器之间,如果某台服务器作为代理来连接后端的服务端,那么这台服务器也会扮演请求方的角色。
-
无状态。这里的状态是指通信过程的上下文信息,而每次 http 请求都是独立、无关的,默认不需要保留状态信息。
HTTP缺点
无状态
无状态这一特点可以是优点也可以是缺点,看场景而定;1,在需要长链接的场景中,要保存大量的上下文信息,避免传输大量重复信息,这是无状态就是http的缺点。2,当一些应用只是为了获取一点点数据,没有保存连接上下文的需要,这是无状态减少了网络的开销。
明文传输
即协议里的报文(主要指的是头部)不使用二进制数据,而是文本形式。 这当然对于调试提供了便利,但同时也让 HTTP 的报文信息暴露给了外界,给攻击者也提供了便利。WIFI陷阱就是利用 HTTP 明文传输的缺点,诱导你连上热点,然后疯狂抓你所有的流量,从而拿到你的敏感信息。
队头阻塞问题
当 http 开启长连接时,共用一个 TCP 连接,同一时刻只能处理一个请求,那么当前请求耗时过长的情况下,其它的请求只能处于阻塞状态,也就是著名的队头阻塞问题。接下来会有一小节讨论这个问题。