HTTP
一、HTTP定义
HTTP定义:HTTP 是超文本传输协议,也就是 HyperText Transfer Protocol。HTTP 是一个在计算机 世界里专门在「两点」之间「传输」文字、图片、音频、视频等「超文本」数据的「约定和 规范」。PS:HTTP 不止是从互联网服务器传输超文本到本地浏览器的协议,还是服务器到 服务器之间的传输协议。
HTTP解析
- HTTP是构建于TCP/IP协议之上,是应用层协议,默认端口号80
- HTTP协议是无连接无状态的
HTTP请求报文格式:
HTTP响应报文格式:
请求行
请求行是由请求方法、url字段以及HTTP协议版本字段三个部分组成,它们用空格分开。
HTTP协议的请求方法有GET、POST、HEAD、PUT、DELETE、OPTIONS、TRACE、CONNECT。
而常见的有如下几种:
1.1 GET
当客户端要从服务器读取数据时,点击网页上的链接,或者通过在浏览器的地址栏输入网址来浏览网页的,使用的都是GET方式。GET的方法要求服务器将URL定位的资源放在响应报文的数据部分,回送给客户端。使用GET的方法,请求参数和对应的值附加在URL后面,利用问号 (?),代表URL的结尾和请求参数的开始,传递的参数长度受到限制。例如,www.baidu.com/index.html?id=1&password=123,这样通过GET的方式传递的数据直接显示在地址上,所以我们可以将请求以链接的方式发送给接收方。可以看到GET的请求一般不包含“请求内容”的部分,请求数据以地址的形式表现在请求行中,地址 ? ?? 之后的部分就是通过GET发送的数据,我们可以在地址栏中看到各种数据之间用 & 符号隔开。
- 但是这种方式显然不能传递私密的数据
- 另外不同浏览器对地址的字符长度限制有不同的数据,一般最多不超过1024个字符,所以大量的数据传输,不适合使用GET方式。
1.2 POST
对于以上适合使用GET方式的情况下,可以使用POST方式,因为使用POST的方法允许客户端给服务端提供较多的信息。POST将请求参数封装在HTTP的请求数据中,可以大量的传递数据,理论上对数据得大小的没有限制,但实际各个WEB服务器会规定对post提交数据大小进行限制。而且可以不显示在URL中。下图是用wireshark抓的一个POST请求的报文,红色为请求报文,蓝色为响应报文。可以看到POST方式的请求行中不包括字符串数据,这些内容保存在“请求内容”部分,各个数据之间也是以 & 符号隔开。
请求头 | 含义 |
User-Agent | 产生请求的浏览器类型,User-Agent请求报头域允许客户端将它的操作系统、浏览器和其它属性告诉服务器 |
Accept | 客户端可识别的响应内容类型列表。eg:Accept:image/gif,表明客户端希望接受GIF图象格式的资源;Accept:text/html,表明客户端希望接受html文本。 |
Accept-Language | 客户端可接受的自然语言 |
Accept-chartset | 客户端可接受应答的字符集。eg:Accept-Charset:iso-8859-1,gb2312.如果在请求消息中没有设置这个域,缺省是任何字符集都可以接受。 |
Accept-Encoding | 客户端可接受的编码压缩格式 |
HOST | 请求的主机名称,允许多个域名同处一个IP之地,即虚拟主机 |
Connection | 连接方式(close或keep-alive) |
Cookie | 存储于客户端扩展字段,向同一域名的服务端发送该域的cookie |
Authorization | Authorization请求报头域主要用于证明客户端有权查看某个资源。当浏览器访问一个页面时,如果收到服务器的响应代码为401( |
1.3 GET 和 POST 基本区别
- GET产生一个TCP数据包;POST产生两个TCP数据包。
对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);
对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。
- GET在浏览器回退时是无害的,而POST会再次提交请求。
- GET产生的URL地址可以被Bookmark,而POST不可以。
- GET请求会被浏览器主动cache,而POST不会,除非手动设置。
- GET请求只能进行url编码,而POST支持多种编码方式。
- GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。
- GET请求在URL中传送的参数是有长度限制的,而POST没有。
- 对参数的数据类型,GET只接受ASCII字符,而POST没有限制。
- GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。
- GET参数通过URL传递,POST放在Request body中。
参考: https://www.cnblogs.com/logsharing/p/8448446.html
HTTP 状态码
http各个状态码的含义:由三位数字组成,第一位定义了状态码的类型
2开头:(请求成功)表示成功处理了请求的状态代码
- 200:(成功)服务器已成功处理了请求。通常,这表示服务器提供了请求的网页。
- 201:(已创建)请求成功并且服务器创建了新的资源
- 202:(已接受)服务器已接受请求,但尚未处理
- 203:(非授权信息)服务器已成功处理了请求,但返回的信息可能来自另一资源。
- 204:(无内容)服务器成功处理了请求,但没有返回任何内容
- 205:(重置内容)服务器成功处理了请求,但没有返回任何内容
- 206:(部分内容)服务器成功处理了部分 GET 请求
3开头:(请求被重定向)表示要完成请求,需要进一步操作。通常,这些状态代码用来重定向
- 300:(多种选择)针对请求,服务器可执行多种操作。服务器可根据请求者(user agent)选择一项操作,或提供操作列表供请求者选择
- 301:(永久移动)请求的网页已永久移动到新位置。服务器返回此响应(对 GET 或 HEAD 请求的响应)时,会自动将请求者转到新的位置
- 302:(临时移动)服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求
- 303:(查看其他位置)请求者应当对不同的位置使用单独的 GET 请求来检索响应时,服务器返回此代码
- 304:(未修改)自从上次请求后,请求的网页未修改过。服务器返回此响应,不会返回网页内容
- 305:(使用代理)请求者只能使用代理访问请求的网页。如果服务器返回此响应,还表示请求者应使用代理
- 307:(临时重定向)服务器目前从不同位置的网页响应请求,但请求者继续使用原有位置来进行以后的请求
4开头:(请求错误)这些状态码表示请求可能出错,妨碍了服务器的处理
- 400:(错误请求)服务器不理解请求的语法
- 401:(未授权)请求要求身份验证。对于需要登录的网页,服务器可能返回此响应
- 403:(禁止)服务器拒绝请求
- 404:(未找到)服务器找不到请求的网页
- 405:(方法禁用)禁用请求中指定的方法
- 406:(不接受)无法使用请求的内容特性响应请求的网页
- 407:(需要代理授权)此状态代码与 401 (未授权)类似,但指定请求者应当授权使用代理
- 408:(请求超时)服务器等候请求时发生超时
- 409:(冲突)服务器在完成请求时发生冲突。服务器必须在响应中包含有关冲突的信息
- 410:(已删除)如果请求的资源已永久删除,服务器就会返回此响应
- 411:(需要有效长度)服务器不接受不含有效内容长度标头字段的请求
- 412:(未满足前提条件)服务器未满足请求者在请求中设置的其中一个前提条件
- 413:(请求实体过大)服务器无法处理请求,因为请求实体过大,超出服务器的处理能力
- 414:(请求的 URI 过长)请求的URI(通常为网址)过长,服务器无法处理
- 415:(不支持的媒体类型)请求的格式不受请求页面的支持
- 416:(请求范围不符合)如果页面无法提供请求的范围,则服务器返回此状态代码
- 417:(未满足期望值)服务器未满足“期望”请求标头字段要求
5开头:(服务器错误)这些状态代码表示服务器在尝试处理请求时发生内部错误。这些错误可能是服务器本身的错误,而不是请求出错。
- 500:(服务器内部错误)服务器遇到错误,无法完成请求
- 501:(尚未实施)服务器不具备完成请求的功能。例如,服务器无法识别请求方法时可能会返回此代码
- 502:(错误网关)服务器作为网关或代理,从上游服务器收到无效响应
- 503:(服务不可用)服务器目前无法使用(由于超载或停机维护)。通常,这只是暂时状态
- 504:(网关超时)服务器作为网关或代理,但是没有及时从上游服务器收到请求
- 505:(HTTP 版本不受支持)服务器不支持请求中所用的 HTTP 协议版本
参考:https://www.cnblogs.com/maigy/p/11480011.html
HTTP特性
优点是「简单、灵活和易于扩展、应用广泛和跨平台」。
- 简单:HTTP 基本的报文格式就是 header + body ,头部信息也是 key-value 简单文本的形式,易 于理解,降低了学习和使用的门槛。
- 灵活和易于扩展:HTTP 协议里的各类请求方法、URI/URL、状态码、头字段等每个组成要求都没有被固定死, 都允许开发人员自定义和扩充。同时 HTTP 由于是工作在应用层( OSI 第七层),则它下 层可以随意变化。HTTPS 也就是在 HTTP 与 TCP 层之间增加了 SSL/TLS 安全传输层, HTTP/3 甚至把 TCP 层换成了基于 UDP 的 QUIC。
- 应用广泛和跨平台:互联网发展至今,HTTP 的应用范围非常的广泛,从台式机的浏览器到手机上的各种 APP, 同时天然具有跨平台的优越性。 HTTP 协议里有优缺点一体的双刃剑,分别是「无状态、明文传输」,同时还有一大缺点「不安全」。无状态:
- 无状态的好处,因为服务器不会去记忆 HTTP 的状态,所以不需要额外的资源来记录状态 信息,这能减轻服务器的负担,能够把更多的 CPU 和内存用来对外提供服务。
- 无状态的坏处,既然服务器没有记忆能力,它在完成有关联性的操作时会非常麻烦。例如登录->添加购 物车->下单->结算->支付,这系列操作都要知道用户的身份才行。但服务器不知道这 些请求是有关联的,每次都要问一遍身份信息。这样每操作一次,都要验证信息,这种体验对用户来说很不友好。对于无状态的问题,解法方案有很多种,其中比较简单的方式用 Cookie 技术。Cookie 通过在请求和响应报文中写入 Cookie 信息来控制客户 端的状态。相当于,在客户端第一次请求后,服务器会下发一个装有客户信息的「小贴纸」, 后续客户端请求服务器的时候,带上「小贴纸」,服务器就能认得了。
- 明文传输:
- 不安全
- 方便阅读
HTTP不同版本的特点
HTTP 1.0
HTTP1.0 的缺陷
- 高延迟 — 队头阻塞(Head-Of-Line Blocking)
- 无状态特性 — 阻碍交互
- 明文传输 — 不安全性
- 不支持服务端推送
1.0版本的HTTP,是一种无状态,无连接的应用层协议。HTTP1.0规定浏览器和服务器保持短暂的链接。
浏览器每次请求都需要与服务器建立一个TCP连接,服务器处理完成以后立即断开TCP连接(无连接),服务器不跟踪也每个客户单,也不记录过去的请求(无状态)。这种无状态性可以借助cookie/session机制来做身份认证和状态记录。
存在的问题
(1)队头阻塞
队头阻塞:队头阻塞是指当顺序发送的请求序列中的一个请求因为某种原因被阻塞时,在后面排队的所有请求也一并被阻塞,会导致客户端迟迟收不到数据。
(2)无状态连接
(3)不安全性
- 无法复用连接,每次发送请求,都需要进行一次TCP连接,而TCP的连接释放过程又是比较费事的。这种无连接的特性会使得网络的利用率变低。
- 队头阻塞(head of line blocking),由于HTTP1.0规定下一个请求必须在前一个请求响应到达之前才能发送,假设前一个请求响应一直不到达,那么下一个请求就不发送,后面的请求就阻塞了。
- 不支持断点续传,也就是说,每次都会传送全部的页面和数据。
HTTP 1.1
HTTP1.1继承了HTTP1.0的简单,克服了HTTP1.0性能上的问题。
针对队头阻塞:
- 将同一页面的资源分散到不同域名下,提升连接上限。虽然能公用一个 TCP 管道,但是在一个管道中同一时刻只能处理一个请求,在当前的请求没有结束之前,其他的请求只能处于阻塞状态。
- 减少请求数量
- 内联一些资源:css、base64图片等
- 合并小文件减少资源数
- 无状态特性:无状态是指协议对于连接状态没有记忆能力。纯净的 HTTP 是没有 cookie 等机制的,每一个连接都是一个新的连接。上一次请求验证了用户名密码,而下一次请求服务器并不知道它与上一条请求有何关联,换句话说就是掉登录态。
- 不安全性:传输内容没有加密,中途可能被篡改和劫持。
(4)SPDY协议
SPDY 是由 google 推行的改进版本的 HTTP1.1 (那时候还没有 HTTP2)。
特点:
- 多路复用 — 解决队头阻塞
SPDY 允许在一个连接上无限制并发流。因为请求在一个通道上,TCP 效率更高(参考 TCP 拥塞控制 中的慢启动)。更少的网络连接,发出更密集的包。 - 头部压缩 — 解决巨大的 HTTP 头部
使用专门的 HPACK 算法,每次请求和响应只发送差异头部,一般可以达到 50%~90% 的高压缩率。 - 请求优先级 — 先获取重要数据
虽然无限的并发流解决了队头阻塞的问题,但如果带宽受限,客户端可能会因防止堵塞通道而阻止请求。在网络通道被非关键资源堵塞时,高优先级的请求会被优先处理。 - 服务端推送 — 填补空缺
服务端推送(ServerPush),可以让服务端主动把资源文件推送给客户端。当然客户端也有权利选择是否接收。 - 提高安全性
支持使用 HTTPS 进行加密传输。
特点
- 长连接,HTTP1.1增加Connection字段,对于同一个host,通过设置Keep-Alive保持HTTP连接不断。避免每次客户端与服务器请求都要重复建立释放建立TCP连接。提高了网络的利用率。如果客户端想关闭HTTP连接,可以在请求头中携带Connection:false来告知服务器关闭请求。
- 支持断点续传,通过使用请求头中的 Range 来实现。
- 可以使用管道传输,多个请求可以同时发送,但是服务器还是按照顺序,先回应 A 请求,完成后再回应 B 请求。要是 前面的回应特别慢,后面就会有许多请求排队等着。这称为「队头堵塞」。