HTTP
HTTP协议的发展历史
说的HTTP 我们需要先了解一下HTTP的发展历史
HTTP/0.9
第一个定稿的HTTP协议 HTTP/0.9
-
规定了HTTP使用TCP/IP连接
-
只有一个请求行,没有header等描述数据的信息
-
只有一个 GET 请求方法
-
HTTP相应则直接返回HTML文本,
-
没有状态码,所以也没有办法区分错误消息和正常的文本。 只能通过ASCII字符流进行传输
-
服务器发送完毕内容,就关闭TCP连接
第二个HTTP版本 HTTP/1.0 正式作为标准
- 增加了请求头域和相应头域
- 增加了HEAD 和POST,PUT等 请求方法
- 响应对象不再局限于HTML文本
- 支持长连接和缓存机制
- 增加了状态码
- 但不是持久连接
HTTP/1.1 在HTTP1.0上增加了一些功能
-
持久连接 一个TCP连接上可以传输多个HTTP请求,只要浏览器或者服务器没有断开连接,该TCP会一直保持。 持久连接默认是开启的 keep-alive: connective
-
pipeline (管道机制)(可以在一个连接中发送多个请求,但是在服务端我们还是按照顺序进行任务的返回,比如前一个请求处理时间较长,后一个请求处理较快,那么这时后一个请求不能先发送,它得等第一个请求数据发送完成后,再发送) 头部阻塞
-
增加host 增加对虚拟主机的支持
HTTP/1.0中每个域名都只绑定唯一的IP地址,因此一个服务器只能支持一个域名
但是随着虚拟主机技术的发展,一台物理主机上绑定多个虚拟主机的需求大大提升,每个虚拟主机都有自己单独的域名,这些单独的域名都公用同一个IP地址。
-
HTTP1.1 引入了客户端cookie机制
-
增加对动态生产内容的支持 (分块传输编码)
HTTP/1.0需要在响应头中设置完整的数据大小Content-Length:900,这样,浏览器就可以根据设置的数据大小来接收数据。
由于服务器端技术发展,页面都是动态生成的,传输数据之前并不知道最终数据大小,导致浏览器不知道何时会接受完所有的文件数据。
HTTP/1.1通过引入Chunk transfer机制来解决问题,服务器将数据分割成若干个任意大小的数据块,每个数据块发送时会附上上一个数据块的长度,最后使用一个长度为0的块作为发送数据完成的标志。
HTTP2.0
HTTP1.1的缺陷
对宽带的利用率而不理想,三个问题导致:
- TCP慢启动
- 同时开启多条TCP连接,那么这些连接会竞争固定的宽带
- HTTP/1.1 队头阻塞问题
HTTP2.0解决了哪些问题
-
所有数据以二进制传输
一个域名只使用一个 TCP 长连接和消除队头阻塞问题。通过引入二进制分帧层,实现了 HTTP 的多路复用技术。
-
多路复用
-
头部压缩
HTTP/2开发了“HPACK”算法,在客户端和服务器建立“字典”,用索引号表示重复的字符串,还采用哈夫曼编码来压缩整数和字符串。
-
服务器推送
服务器可以提前将数据推送到浏览器
-
请求优先级
HTTP/3.0
HTTP/2的缺陷
- TCP的队头阻塞
- TCP建立连接的延迟
HTTP3 基于QUIC协议
HTTP/3 选择了一个折衷的方法——UDP 协议,基于 UDP 实现了类似于 TCP 的多路数据流、传输可靠性等功能,我们把这套功能称为QUIC 协议。
-
实现了类似 TCP 的流量控制、传输可靠性的功能
-
集成了 TLS 加密功能
-
实现了 HTTP/2 中的多路复用功能
-
实现了快速握手功能
HTTP协议
http 是基于请求于相应,无状态的应用层协议, 常基于TCP/IP协议传输数据
应用层
应用层协议定义了应用进程间的交互和通信规则,不同主机的应用进程间如何相互传递报文,比如传递的报文的类型、格式、 有哪些字段等等
概况
- HTTP 是超文本传输协议,它定义了客户端和服务器之间交换报文的格式和方式,默认使用 80 端口。它使用 TCP 作为传输层协议,保证了数据传输的可靠性。
- HTTP 是一个无状态的协议,HTTP 服务器不会保存关于客户的任何信息。
- HTTP 有两种连接模式,一种是持续连接,一种非持续连接。非持续连接指的是服务器必须为每一个请求的对象建立和维护 一个全新的连接。持续连接下,TCP 连接默认不关闭,可以被多个请求复用。采用持续连接的好处是可以避免每次建立 TCP 连接三次握手时所花费的时间。在 HTTP1.0 以前使用的非持续的连接,但是可以在请求时,加上 Connection: keep-alive 来要求服务器不要关闭 TCP 连接。HTTP1.1 以后默认采用的是持续的连接。目前对于同一个域,大多数浏览器支持 同时建立 6 个持久连接。
HTTP请求报文
HTTP 报文有两种,一种是请求报文,一种是响应报文。
HTTP 请求报文的格式如下:
GET / HTTP/1.1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5)
Accept: */*
HTTP 请求报文的第一行叫做请求行,后面的行叫做首部行,首部行后还可以跟一个实体主体。请求首部之后有一个空行,这个空行不能省略,它用来划分首部与实体。
请求行包含三个字段:方法字段、URL 字段和 HTTP 版本字段。
方法字段可以取几种不同的值,一般有 GET、POST、HEAD、PUT 和 DELETE。一般 GET 方法只被用于向服务器获取数据。 POST 方法用于将实体提交到指定的资源,通常会造成服务器资源的修改。HEAD 方法与 GET 方法类似,但是在返回的响应中,不包含请求对象。PUT 方法用于上传文件到服务器,DELETE 方法用于删除服务器上的对象。虽然请求的方法很多,但 更多表达的是一种语义上的区别,并不是说 POST 能做的事情,GET 就不能做了,主要看我们如何选择。更多的方法可以参看文档。
HTTP相应报文
HTTP/1.0 200 OK
Content-Type: text/plain
Content-Length: 137582
Expires: Thu, 05 Dec 1997 16:00:00 GMT
Last-Modified: Wed, 5 August 1996 15:55:28 GMT
Server: Apache 0.84
<html>
<body>Hello World</body>
</html>
HTTP 响应报文的第一行叫做状态行,后面的行是首部行,最后是实体主体。
状态行包含了三个字段:协议版本字段、状态码和相应的状态信息。
实体部分是报文的主要部分,它包含了所请求的对象。
状态码: 一般 1XX 代表服务器接收到请求、2XX 代表成功、3XX 代表重定向、4XX 代表客户端错误、5XX 代表服务器端错误。
首部行
首部可以分为四种首部,请求首部、响应首部、通用首部和实体首部。通用首部和实体首部在请求报文和响应报文中都可以设置,区别在于请求首部和响应首部。
常见的请求首部有 Accept 可接收媒体资源的类型、Accept-Charset 可接收的字符集、Host 请求的主机名。
常见的响应首部有 ETag资源的匹配信息(304),Location 客户端重定向的 URI。(301)
常见的通用首部有 Cache-Control 控制缓存策略、Connection 管理持久连接。
常见的实体首部有 Content-Length 实体主体的大小、Expires 实体主体的过期时间、Last-Modified 资源的最后修改时间。
更多关于首部的资料可以查看:
HTTP /1.1 协议的缺点
HTTP/1.1 默认使用了持久连接,多个请求可以复用同一个 TCP 连接,但是在同一个 TCP 连接里面,数据请求的通信次序 是固定的。服务器只有处理完一个请求的响应后,才会进行下一个请求的处理,如果前面请求的响应特别慢的话,就会造成许 多请求排队等待的情况,这种情况被称为“队头堵塞”
。队头阻塞会导致持久连接在达到最大数量时,剩余的资源需要等待其他 资源请求完成后才能发起请求。
为了避免这个问题,一个是减少请求数,一个是同时打开多个持久连接。这就是我们对网站优化时,使用雪碧图、合并脚本的原因。
http1.1 和http1.0 的区别
http1.1 相对于 http1.0 有这样几个区别:
(1)连接方面的区别,http1.1 默认使用持久连接,而 http1.0 默认使用非持久连接。http1.1 通过使用持久连接来使多个 http 请求复用同一个 TCP 连接,以此来避免使用非持久连接时每次需要建立连接的时延。
(2)资源请求方面的区别,在 http1.0 中,存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,并且不支持断点续传功能,http1.1 则在请求头引入了 range 头域,它允许只请求资源的某个部分,即返回码是 206(Partial Content),这样就方便了开发者自由的选择以便于充分利用带宽和连接。
(3)缓存方面的区别,在 http1.0 中主要使用 header 里的 If-Modified-Since,Expires 来做为缓存判断的标准,http1.1 则引入了更多的缓存控制策略例如 Etag、If-Unmodified-Since、If-Match、If-None-Match 等更多可供选择的缓存头来控制缓存策略。
(4)http1.1 中还新增了 host 字段,用来指定服务器的域名。http1.0 中认为每台服务器都绑定一个唯一的 IP 地址,因此,请求消息中的 URL 并没有传递主机名(hostname)。但随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机,并且它们共享一个IP地址。因此有了 host 字段,就可以将请求发往同一台服务器上的不同网站。
(5)http1.1 相对于 http1.0 还新增了很多方法,如 PUT、POST,HEAD、OPTIONS 等。
(6) 在HTTP1.1中新增了24个错误状态响应码,如409(Conflict)表示请求的资源与资源的当前状态发生冲突;410(Gone)表示服务器上的某个资源被永久性的删除。
SPDY: HTTP1.x的优化
2012年google如一声惊雷提出了SPDY的方案,优化了HTTP1.X的请求延迟,解决了HTTP1.X的安全性,具体如下:
降低延迟,针对HTTP高延迟的问题,SPDY优雅的采取了多路复用(multiplexing)。多路复用通过多个请求stream共享一个tcp连接的方式,解决了HOL blocking的问题,降低了延迟同时提高了带宽的利用率。
请求优先级(request prioritization)。多路复用带来一个新的问题是,在连接共享的基础之上有可能会导致关键请求被阻塞。SPDY允许给每个request设置优先级,这样重要的请求就会优先得到响应。比如浏览器加载首页,首页的html内容应该优先展示,之后才是各种静态资源文件,脚本文件等加载,这样可以保证用户能第一时间看到网页内容。
**header压缩。**前面提到HTTP1.x的header很多时候都是重复多余的。选择合适的压缩算法可以减小包的大小和数量。
基于HTTPS的加密协议传输,大大提高了传输数据的可靠性。
服务端推送(server push),采用了SPDY的网页,例如我的网页有一个sytle.css的请求,在客户端收到sytle.css数据的同时,服务端会将sytle.js的文件推送给客户端,当客户端再次尝试获取sytle.js时就可以直接从缓存中获取到,不用再发请求了。SPDY构成图:
SPDY位于HTTP之下,TCP和SSL之上,这样可以轻松兼容老版本的HTTP协议(将HTTP1.x的内容封装成一种新的frame格式),同时可以使用已有的SSL功能。
HTTP2.0: SPYD的升级版
HTTP2.0可以说是SPDY的升级版(其实原本也是基于SPDY设计的),但是,HTTP2.0 跟 SPDY 仍有不同的地方,如下:
HTTP2.0和SPDY 的区别
HTTP2.0和HTTP1.X相比的新特性
-
新的二进制格式(Binary Format),HTTP1.x的解析是基于文本。基于文本协议的格式解析存在天然缺陷,文本的表现形式有多样性,要做到健壮性考虑的场景必然很多,二进制则不同,只认0和1的组合。基于这种考虑HTTP2.0的协议解析决定采用二进制格式,实现方便且健壮。
-
多路复用(MultiPlexing),即连接共享,即每一个request都是是用作连接共享机制的。一个request对应一个id,这样一个连接上可以有多个request,每个连接的request可以随机的混杂在一起,接收方可以根据request的 id将request再归属到各自不同的服务端请求里面。
-
header压缩,如上文中所言,对前面提到过HTTP1.x的header带有大量信息,而且每次都要重复发送,HTTP2.0使用encoder来减少需要传输的header大小,通讯双方各自cache一份header fields表,既避免了重复header的传输,又减小了需要传输的大小。
-
服务端推送(server push),同SPDY一样,HTTP2.0也具有server push功能。
-
请求优先级
《HTTP1.0、HTTP1.1 和 HTTP2.0 的区别》
HTTP2.0 有哪些特点
回顾HTTP1.1
1、长连接
Http1.1支持长连接(PersistentConnection)和请求的流水线(Pipelining)处理,在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟,在HTTP1.1中默认开启Connection: keep-alive,一定程度上弥补了HTTP1.0每次请求都要创建连接的缺点。
2、缓存处理
引入了更多的缓存控制策略例如Entity tag,If-Unmodified-Since, If-Match, If-None-Match等更多可供选择的缓存头来控制缓存策略。
3、带宽优化及网络连接的使用
在请求头引入了range头域,它允许只请求资源的某个部分,即返回码是206(Partial Content),这样就方便了开发者自由的选择以便于充分利用带宽和连接。
4、错误通知的管理
新增了24个错误状态响应码,如409(Conflict)表示请求的资源与资源的当前状态发生冲突;410(Gone)表示服务器上的某个资源被永久性的删除。
5、Host头处理
Http1.1的请求消息和响应消息都应支持Host头域,且请求消息中如果没有Host头域会报告一个错误(400 Bad Request)。
HTTP2.0 新特性
1、完全采用二进制格式
HTTP2.0主要改动HTTP2.0作为新版协议,改动细节必然很多,不过对应用开发者和服务提供商来说,影响较大的就几点。
新的二进制格式(Binary Format)http1.x诞生的时候是明文协议,其格式由三部分组成:start line(request line或者status line),header,body。要识别这3部分就要做协议解析,http1.x的解析是基于文本。基于文本协议的格式解析存在天然缺陷,文本的表现形式有多样性,要做到健壮性考虑的场景必然很多,二进制则不同,只认0和1的组合。基于这种考虑http2.0的协议解析决定采用二进制格式,实现方便且健壮。
有人可能会觉得基于文本的http调试方便很多,像firebug,chrome,charles等不少工具都可以即时调试修改请求。实际上现在很多请求都是走https了,要调试https请求必须有私钥才行。http2.0的绝大部分request应该都是走https,所以调试方便无法作为一个有力的考虑因素了。curl,tcpdump,wireshark这些工具会更适合http2.0的调试。
http2.0用binary格式定义了一个一个的frame,和http1.x的格式对比如下图:
2、多路复用
根据request的 id将request再归属到各自不同的服务端请求里面,即单个连接上同时进行多个业务单元数据的传输。
3、头部压缩
假定一个页面有100个资源需要加载(这个数量对于今天的Web而言还是挺保守的), 而每一次请求都有1kb的消息头(这同样也并不少见,因为Cookie和引用等东西的存在), 则至少需要多消耗100kb来获取这些消息头。HTTP2.0可以维护一个字典,差量更新HTTP头部,大大降低因头部传输产生的流量。
使用encoder来减少需要传输的header大小,通讯双方各自cache一份header fields表,既避免了重复header的传输,又减小了需要传输的大小。
HTTP1.X的头部越来越膨胀,很多都是重复且多余的,HTTP2.0可以压缩头部的大小,并且避免了重复的传输,可以大大降低延迟。
4、服务端推送
服务端推送能把客户端所需要的资源伴随着index.html一起发送到客户端,省去了客户端重复请求的步骤。正因为没有发起请求,建立连接等操作,所以静态资源通过服务端推送的方式可以极大地提升速度。
5、请求优先级
HTTP2.0的多路复用解决了HTTP1.X中的长连接复用的什么痛点?
HTTP/1.* 一次请求-响应,建立一个连接,用完关闭;每一个请求都要建立一个连接;
HTTP/1.1 Pipeling解决方式为,若干个请求排队串行化单线程处理,后面的请求等待前面请求的返回才能获得执行机会,一旦有某请求超时等,后续请求只能被阻塞,毫无办法,也就是人们常说的线头阻塞;
也就是说,HTTP1.1尽管减少了TCP连接的消耗,但是本身仍然是串行执行。
HTTP2.0多个请求可同时在一个连接上并行执行。某个请求任务耗时严重,不会影响到其它连接的正常执行;
HTTP2.0多路复用的优势
HTTP性能优化的关键并不在于高带宽,而是低延迟。TCP 连接会随着时间进行自我「调谐」,起初会限制连接的最大速度,如果数据成功传输,会随着时间的推移提高传输的速度。这种调谐则被称为 TCP 慢启动。由于这种原因,让原本就具有突发性和短时性的 HTTP 连接变的十分低效。
HTTP/2 通过让所有数据流共用同一个连接,可以更有效地使用 TCP 连接,让高带宽也能真正的服务于 HTTP 的性能提升。
HTTP3.0
http3.0 使用的是udp协议
HTTP2.0 的不足
- 建立连接实践长 (本质上是TCP的问题)
- 队头阻塞问题
- 移动互联网领域表现不佳(弱网环境)
- …
HTTP2.0的缺点基本都是由于TCP协议引起的. 水能载舟亦能覆舟
HTTP3.0又称为HTTP Over QUIC
,其弃用TCP协议,改为使用基于UDP协议的QUIC协议来实现。
HTTP状态码
常见状态码
各类别常见状态码
2xx
-
200 (成功) 服务器已成功处理了请求。 通常,这表示服务器提供了请求的网页。
-
201 (已创建) 请求成功并且服务器创建了新的资源。
-
202 (已接受) 服务器已接受请求,但尚未处理。
-
203 (非授权信息) 服务器已成功处理了请求,但返回的信息可能来自另一来源。
-
204 (无内容) 服务器成功处理了请求,但没有返回任何内容。
-
205 (重置内容) 服务器成功处理了请求,但没有返回任何内容。
-
206 (部分内容) 服务器成功处理了部分 GET 请求。
3xx
-
300 (多种选择) 针对请求,服务器可执行多种操作。 服务器可根据请求者 (user agent) 选择一项操作,或提供操作列表供请求者选择。
-
301 (永久移动) 请求的网页已永久移动到新位置。 服务器返回此响应(对 GET 或 HEAD 请求的响应)时,会自动将请求者转到新位置。 Location
-
302 (临时移动) 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。
-
303 (查看其他位置) 请求者应当对不同的位置使用单独的 GET 请求来检索响应时,服务器返回此代码。
-
304 (未修改) 自从上次请求后,请求的网页未修改过。 服务器返回此响应时,不会返回网页内容。
-
305 (使用代理) 请求者只能使用代理访问请求的网页。 如果服务器返回此响应,还表示请求者应使用代理。
-
307 (临时重定向) 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。
301和302区别:前者是永久移动,后者是临时移动(之后可能还会更改URL)
302和303区别:后者明确表示客户端应当采用GET方式获取资源
4xx
-
400 (错误请求) 服务器不理解请求的语法。
-
401 (未授权) 请求要求身份验证。 对于需要登录的网页,服务器可能返回此响应。
-
403 (禁止) 服务器拒绝请求。
-
404 (未找到) 服务器找不到请求的网页。
-
405 (方法禁用) 禁用请求中指定的方法。
-
406 (不接受) 无法使用请求的内容特性响应请求的网页。
-
407 (需要代理授权) 此状态代码与 401(未授权)类似,但指定请求者应当授权使用代理。
-
408 (请求超时) 服务器等候请求时发生超时。
-
409 (冲突) 服务器在完成请求时发生冲突。 服务器必须在响应中包含有关冲突的信息。
-
410 (已删除) 如果请求的资源已永久删除,服务器就会返回此响应。
-
411 (需要有效长度) 服务器不接受不含有效内容长度标头字段的请求。
-
412 (未满足前提条件) 服务器未满足请求者在请求中设置的其中一个前提条件。
-
413 (请求实体过大) 服务器无法处理请求,因为请求实体过大,超出服务器的处理能力。
-
414 (请求的 URI 过长) 请求的 URI(通常为网址)过长,服务器无法处理。
-
415 (不支持的媒体类型) 请求的格式不受请求页面的支持。
-
416 (请求范围不符合要求) 如果页面无法提供请求的范围,则服务器会返回此状态代码。
-
417 (未满足期望值) 服务器未满足"期望"请求标头字段的要求。
5xx
-
500 (服务器内部错误) 服务器遇到错误,无法完成请求。
-
501 (尚未实施) 服务器不具备完成请求的功能。 例如,服务器无法识别请求方法时可能会返回此代码。
-
502 (错误网关) 服务器作为网关或代理,从上游服务器收到无效响应。
-
503 (服务不可用) 服务器目前无法使用(由于超载或停机维护)。 通常,这只是暂时状态。
-
504 (网关超时) 服务器作为网关或代理,但是没有及时从上游服务器收到请求。
-
505 (HTTP 版本不受支持) 服务器不支持请求中所用的 HTTP 协议版本。
常考状态码
常用的HTTP状态码:2XX-请求成功、3XX-重定向、301-永久重定向、302-临时重定向、303-请求其他资源、4XX-客户端错误、401-未认证、403-被拒绝、404-资源不存在、405-不允许使用该方法、5XX服务器端错误、500-服务器内部错误、502-错误网关、503-服务不可用、504-网关超时。
以上这些状态码会经常用于判断服务的可用性上,也很方便适用于前后端联调时出错的判断。
-
206 Partial Content 部分内容
服务器成功处理了部分GET请求.
http1.1 带宽优化及网络连接的使用
-
301 Moved Permanently 永久移动 请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替
-
302 Found 临时移动 客户端应继续使用原有URI
-
304 Not Modified 未修改。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源
-
400 Bad Request 客户端请求的语法错误,服务器无法理解
-
401 Unauthorized 请求要求用户的身份认证
-
403 Forbidden 服务器理解请求客户端的请求,但是拒绝执行此请求
-
404 Not Found 服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置”您所请求的资源无法找到”的个性页面
-
405 Method Not Allowed 客户端请求中的方法被禁止
-
500 Internal Server Error 服务器内部错误,无法完成请求
-
502 Bad Gateway 充当网关或代理的服务器,从远端服务器接收到了一个无效的请求
-
503 Service Unavailable 由于超载或系统维护,服务器暂时的无法处理客户端的请求。延时的长度可包含在服务器的Retry-After头信息中
-
504 Gateway Time-out 充当网关或代理的服务器,未及时从远端服务器获取请求
HTTPS和HTTP
- HTTPS协议需要到CA申请证书,一般免费证书很少,需要交费。
- HTTP协议运行在TCP之上,所有传输的内容都是明文,HTTPS运行在SSL/TLS之上,SSL/TLS运行在TCP之上,所有传输的内容都经过加密的。
- HTTP和HTTPS使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
- HTTPS可以有效的防止运营商劫持,解决了防劫持的一个大问题。
HTTP缓存策略
浏览器缓存
- Memory Cache
- Servier Worker Cache 以https为前提
- HTTP Cache 常用 强缓存和协商缓存
- Push Cache HTTP2 的服务器缓存
HTPP轮询模型
长轮询和短轮询
长连接是值TCP连接不是HTTP连接
post和get的区别
幂等: 它描述了一次和多次请求某一个资源对于资源本身应该具有同样的结果
Post 和 Get 是 HTTP 请求的两种方法。
-
从应用场景上来说,GET 请求是一个幂等的请求,一般 Get 请求用于对服务器资源不会产生影响的场景,比如说请求一个网页。而 Post 不是一个幂等的请求,一般用于对服务器资源会产生影响的情景。比如注册用户这一类的操作。
-
因为不同的应用场景,所以浏览器一般会对 Get 请求缓存,但很少对 Post 请求缓存。
-
从发送的报文格式来说,Get 请求的报文中实体部分为空,Post 请求的报文中实体部分一般为向服务器发送的数据。
-
但是 Get 请求也可以将请求的参数放入 url 中向服务器发送,
这样的做法相对于 Post 请求来说,一个方面是不太安全,因为请求的 url 会被保留在历史记录中。并且浏览器由于对url 有一个长度上的限制,所以会影响 get 请求发送数据时的长度。这个限制是浏览器规定的,并不是 RFC 规定的。有就是 post 的参数传递支持更多的数据类型。