前言
今天为大家整理了一份各大佬在面试中遇到的HTTP知识点汇总,希望对大家有帮助,正文开始!
1.HTTP到底是什么
HTTP 是一种超文本传输协议(Hypertext Transfer Protocol),超文本传输协议该怎么理解是本文要讲的第一个问题,下面对 超文本、传输、协议 这三个名词做一下解释。
超文本
文本比较好理解就是字符串嘛,在计算机刚刚发明的时代网络通信传输的就只是字符串,后面随着技术的发展我们不满足仅限字符串的传输通信,还涉及到 图片、音视频、排版(CSS)、交互行为(JS)等资源的传输。之前传输的文本逐渐丰富起来,这个时候文本的语义就扩大了,我们把语义扩大后的文本称为超文本(Hypertext)。
传输
把上面提到过的超文本解析成二进制的数据包,通过传输载体比如网线等从一台设备传输到另一台设备的过程叫做传输。
协议
计算机之间相互通信需要遵守一定的规则,规则中定义了请求端如何传递参数,响应端如何解析数据,这个就是网络协议。
现在我们知道了 http(超文本传输协议)就是在多台网络设备之间传输 文字、图片、音视频 等超文本内容的具体规范和约定。 网络协议除了http之外,常见的还有 电子邮件传输协议 SMTP、文件上传协议 FTP、域名解析协议 DNS 。
2.一个HTTP请求是怎么完成通信的
常见的场景是客户端在本地发起请求,服务端接收请求响应数据,那这个过程中具体需要哪些机制配合协作呢,HTTP是一个网络通讯协议,除了HTTP之外你肯定还听过TCP/IP协议,TCP/IP是HTTP通信不可或缺的一部分。
3.HTTP 和 TCP/IP 的关系
为什么说TCP/IP是HTTP通信不可或缺的一部分,因为HTTP协议本身并不具备数据传输的能力,HTTP主要负责客户端和服务端之间请求应答的标准定义(比如报文),而数据传输依赖TCP/IP协议,所以理解HTTP要先从TCP/IP开始。
4.TCP/IP
TCP/IP(Transmission Control Protocol/Internet Protocol 传输控制协议/网际协议)主要作用是在不同网络之间实现信息数据的传输,我们虽然称之为TCP/IP协议,但它实际上是一个协议族,包含的不仅仅是 TCP协议 和 IP协议,还有 UDP、ICMP、ARP 等,TCP、IP协议是这里面最核心的两个协议所以称谓用它们指代。
TCP/IP的核心思想是分层管理,分为四层分别是 应用层、传输层、网络层和链路层。分层设计的好处是每一层都只负责自己的任务,不需要考虑其他层的任务,各层交互的时候只需要相互调用接口即可,当然也有劣势每次进行网络通信的时候都需要由下至上一层一层的传递信息,这对性能是有一定影响的。
- 应用层:加密、解密、数据格式化、域名解析,面向业务。HTTP、FTP、DNS
- 传输层:为两台计算机之间提供相互传输数据的能力。TCP、UDP
- 网络层:进行网络连接的建立和终止,以及IP地址的寻找。IP、ICMP、IPV6
- 链路层:用于处理网络连接的硬件部分。
4.1 HTTP
HTTP是TCP/IP应用层的协议,HTTP主要负责客户端和服务端之间请求应答的标准定义(比如报文)。
4.2 FTP
FTP是TCP/IP应用层的协议,FTP是文件传输协议,主要功能用于实现用户间文件分发共享。
4.3 DNS
我们通过IP可以定位带一台设备,当我们打开百度的IP地址http://202.108.22.5/
就打开了百度的首页,但是这个IP地址无疑是反人类的很难记,这就有了域名,所以我们打开http://www.baidu.com/
也能打开百度的首页。
域名到IP的解析就是 DNS(Domain Name System)做的事情了,它作为将域名和IP地址相互映射的一个分布式数据库,能够使人更方便地访问互联网。
DNS协议是用来将域名转换为IP地址的,也可以将IP地址转换为相应的域名地址。目前,对于每一级域名长度的限制是63个字符,域名总长度则不能超过253个字符。
4.4 TCP
TCP(传输控制协议)是TCP/IP传输层的协议,TCP提供可靠的字节流传输能力,“字节流”是指,为了方便传输,将大块数据分割成以报文段为单位的数据包进行传输管理。而“可靠”是指,TCP协议为保证数据可靠的传输采用了三次握手策略。TCP协议把数据包送出去后,不会对传送后的情况置之不理,它一定会向对方确认是否成功送达,如有异常会启动重发机制。HTTP就是使用TCP提供的传输能力进行通信。
4.5 UDP
UDP(用户数据报协议)是TCP/IP传输层的协议,UDP也提供了数据传输能力,UDP协议定义了端口,当数据包到达主机以后,就可以根据端口号找到对应的应用程序了,比较简单,实现容易,但它没有确认机制,数据包一旦发出,无法知道对方是否收到,因此可靠性较差。UDP和TCP很相似,但是更简单,同时可靠性低于TCP,UDP的优点是快速、资源消耗少。
换句话说UDP只管发,不管对方收没收到,像直播、视频聊天这种就可以用UDP,因为这种需求对延时性要求很高,如果用TCP来做视频聊天,网络不好丢包严重时,那TCP就会不断重发,这样就会导致看到的画面可能还是对方一分钟之前的发送的,如果用UDP来做,网络不好时丢包就丢包了,丢包它也不会重发,而是一直发送最新的数据,所以就能保住我看到的画面都是实时的画面。
UDP还有一个应用场景是DNS解析,DNS解析也使用UDP协议,因为UDP协议只要一个请求、一个应答就好了,而使用TCP协议要三次握手四次挥手更加浪费网络资源,基于数据层面考虑,DNS数据包并不是那种大数据包,所以使用UDP不需要考虑分包,如果丢包那么就是全部丢包,如果收到了数据,那就是收到了全部数据,就算是丢包了重新请求一次就好了。
4.6 IP
IP是TCP/IP网络层的协议,IP协议规定使用IP地址来定位互联网上每一台唯一的设备,再利用 ARP 协议获取中转设备的 MAC 地址,以此解决寻址相关问题。
4.7 IPV6
IPV4的地址长度为4个8位字节,IPV4地址迟早会有枯竭的一天,为了解决这个问题,开始了IPV6的研发,IPv6的地址长度则是原来的4倍,一般写成8个16位字节,IPV6的地址是取之不尽,用之不竭的。
5.TCP与UDP
当客户端希望与服务器通过TCP建立连接时,首先会发送一个通信请求,这个请求必须被送到一个明确的地址,并收到回复,在双方完成“握手”过程后,TCP连接建立,直到其中一端关闭再次“握手”断开连接,这就是“三次握手和四次挥手”,而UDP则没有握手和挥手的机制,这也是TCP更加可靠的原因。
6.TCP三次握手
握手过程中使用了TCP的标志 SYN 和 ACK,发送端首先发送一个带有 SYN 标志的数据包给对方,接收端收到后,回传一个带有 SYN/ACK 标志的数据包以示传达确认信息,最后发送端再回传一个带 ACK 标志的确认包,代表握手结束。若在握手过程某个阶段中断,TCP 协议会再次以相同的顺秀发送相同的数据包。
-
第一次握手:客户端发送SYN报文到服务器,并进入SYN已发送状态,服务器接收到SYN报文。(服务器确认了客户端发送正常,自己接收正常)
-
第二次握手:服务器发送SYN+ACK报文到客户端,并进入ACK已发送状态,客户端收到SYN+ACK报文。(客户端确认了服务器接收正常、发送正常,自己接收正常发送正常)
-
第三次握手:客户端向服务器发送确认报文ACK,服务端接收到确认报文ACK,连接成功建立。(服务端确认了客户端接收正常、发送正常,自己接收正常发送正常)
7.TCP四次挥手
-
第一次挥手:当客户端的数据都传输完成后,客户端向服务端发出包含FIN标志位的连接释放报文(当然数据没发完时也可以发送连接释放报文并停止发送数据),需要注意的是客户端发出FIN后就不能发数据了,但是还可以正常收数据。(客户端告诉服务端我的数据发完了)
-
第二次挥手:服务端收到客户端发的FIN报文后给客户端回复确认报文,确认报文包含ACK标志位。此时服务端处于关闭等待状态,而不是立马给客户端发FIN报文,这个状态还要持续一段时间,因为服务端可能还有数据没发完。(服务端告诉客户端你的断开请求我收到了)
-
第三次挥手:服务端将最后的数据发送完毕后向客户端发出连接释放报文,报文包含FIN和ACK标志位,用来关闭服务器端到客户端的数据传送,也就是告诉客户端,我的数据也发送完了,此时服务端处于断开等待状态。(服务端告诉客户端我的数据也发完了)
-
第四次挥手:客户端收到服务端发的FIN报文后,向服务端发出确认报文,确认报文包含ACK标志位,客户端发出确认报文后不是立马释放TCP连接而是要经过2MSL(最长报文段寿命的2倍时长),服务端一旦收到客户端发出的确认报文就会立马释放TCP连接,所以服务端结束TCP连接的时间要比客户端早一些。
8.为什么握手是三次不是两次
三次握手的作用是让服务端和客户端双方明确彼此的发送能力和接收能力都是正常的,不会造成数据丢失保证信息传递的可靠性。而解决这个问题,三次通信是理论上的最小值。 若只有两次握手,第二次握手时服务器给客户端的确认报文如果丢失(客户端接收数据能力异常),此时客户端一直处在等待状态,它并不清楚问题出在哪里是自己第一次握手的报文没有送达服务端还是服务端的响应报文丢失了,导致客户端无法给服务端发送数据。如果是三次握手,即便发生数据丢失也不会有问题,比如第三次握手客户端发的确认报文丢失,服务端在一段时间内没有收到确认报文就会重新进行第二次握手,客户端收到重发的报文后会再次给服务端发送确认报文。
9.为什么挥手是四次不是三次(为什么握手是三次挥手是四次)
因为只有在客户端和服务端都没有数据发送的时候才能断开连接,客户端发出FIN报文时只能保证客户端没有数据发了,服务端还有没有数据发给客户端是不知道的。所以服务端收到客户端的FIN报文后只能先回复客户端一个确认报文来告诉客户端服务端已经收到你的FIN报文了,但服务端还有一些数据没发完,等这些数据发完了服务端才能给客户端发FIN报文(所以不能一次性将确认报文和FIN报文发给客户端)。
10.为什么客户端发出第四次挥手的确认报文后不会立刻释放TCP连接
这里同样是要考虑丢包的问题,如果第四次挥手的报文丢失,服务端没收到确认ACK报文就会重发第三次挥手的报文,这样报文一去一回最长时间就是2MSL,所以客户端需要等这么长时间来确认服务端确实已经收到了。
11.已经建立了连接如果客户端突然出现故障了怎么办
TCP有一个计时器机制,服务端每次接收到客户端的请求都会复位这个计时器,当一定时间没有收到客户端的信息服务端就会发送一个探测报文,如果依然没有响应之后每隔75s重新发送一次,如果连着10个探测报文没有响应服务器就认为客户端出现了故障,会主动关闭连接。
12.当我们在浏览器输入url后发生了什么
我们以http://www.baidu.com/index.html
为例,来分析一下浏览器地址栏输入URL之后发生了什么,这里只分析和网络请求相关的内容,大量页面渲染的东西先不涉及。
- DNS服务器进行域名解析(先查询缓存以及本地hosts)找到
www.baidu.com
所射映的IP地址,然后在客户端发起一个到服务器的TCP连接(三次握手)。 - 客户端通过TCP连接向服务器发送HTTP请求报文,该报文中包含请求资源路径
/index.html
,以及其他参数。 - 服务器接收请求报文,进行请求解析工作,完成数据库查询、磁盘资源读取等,把这些内容封装到HTTP响应报文中并向客户端发送。
- HTTP客户端接收到响应报文后TCP连接关闭(四次挥手)。
- 浏览器渲染内容。
为了方便理解HTTP这里只描述了一个简单的过程,其实真实的 ‘请求->响应’ 要复杂的多,以及页面的渲染这些后面会专门整理一篇。
13.HTTP的特点
-
支持客户/服务器模式
HTTP工作于客户端服务端的架构之上,浏览器作为客户端通过url向web服务器发送请求,web服务器根据接收到的请求向客户端发送响应信息。 -
简单快速
客户端向服务器请求时,只需传送请求方法和路径。请求方法常用的有 GET、HEAD、POST,每种方法客户端与服务器通信的特征不同。由于HTTP协议的简单,使得HTTP服务器的程序规模小,因而通信速度很快,并且HTTP协议使用明文传输开发者不需要借助第三方工具就可以研测。 HTTP协议主要的组成部分是header + body,头部信息就是简单的语义化多行文本,在这基础上 请求头、状态码 等又支持开发者自定义,做到了足够灵活,只要服务端和客户端就请求头字段达成语义一致,新功能就可以被轻松加入进来。 -
灵活
HTTP允许传输任意类型的数据对象,具体的传输类型由Content-Type值确定,可以是 图片(image/png image/gif)、JSON(application/json)、HTML(text/html )等。因为 HTTP 对语言以及平台不做限制,所以有跨语言跨平台的优越性,又因为其本身的简单灵活几乎所有的语言都有HTTP相关的研测方案。 -
无连接
无连接的含义是限制每次连接只处理一个请求,服务器处理完客户端的请求,并收到客户端的应答后即断开连接,采用这种方式可以节约资源。早期这么做的原因是 HTTP 协议产生于互联网,因为服务器需要处理同时面向全世界数十万、百万客户端的网页访问,但每个客户端(即浏览器)与服务器之间交换数据的间歇性较大,并且网页浏览的联想性、发散性导致两次传送的数据关联性很低,大部分通道实际上处于空闲状态、导致占用资源。因此 HTTP 的设计者有意利用这种特点将协议设计为请求时建连接、请求完释放连接,以尽快将资源释放出来服务其他客户端。
随着时间的推移,网页变得越来越复杂,里面可能嵌入了很多图片,这时候每次访问图片都需要建立一次 TCP 连接就显得很低效,后来 Keep-Alive(HTTP1.1) 被提出用来解决效率低的问题。Keep-Alive 功能使客户端到服务器端的连接持续有效,当出现对服务器的后继请求时,Keep-Alive 功能避免了重新建立连接。
我们始终都要认为HTTP请求在结束后连接就会关闭,这是HTTP的特性,因为上层实现在结束后是否关闭连接都不会改变这个特性,这和WebSocket长连接有本质的区别。
-
无状态
HTTP协议是无状态协议,无状态是指协议对于事务处理没有记忆能力,它不会对请求和响应的状态做持久化储存,每个请求都是独立的,如果后续请求需要前面的信息,则它必须重传,无法支持需要连续多个步骤的事务操作,这样可能导致每次连接传送的数据量增大。另一方面因为服务器不需要管理状态所以它的应答是较快的。这种特性有优点也有缺点,优点在于解放了服务器,每一次请求“点到为止”不会造成不必要连接占用,缺点在于每次请求会传输大量重复的内容信息。
客户端与服务器进行动态交互的Web应用程序(webapp)出现之后,HTTP无状态的特性严重阻碍了这些webapp的实现,毕竟交互是需要承前启后的,于是两种用于保持 HTTP 连接状态的技术就应运而生了,一个是 Cookie,而另一个则是 Session。
Cookie可以保持登录信息到用户下次与服务器的会话,换句话说,下次访问同一网站时,用户会发现不必输入用户名和密码就已经登录了(当然,不排除用户手工删除Cookie)。而还有一些Cookie在用户退出会话的时候就被删除了,这样可以有效保护个人隐私。
Session可以理解是服务端的Cookie,当客户端访问服务器时,服务器根据需求设置 Session,将会话信息保存在服务器上,同时将 Session 的 SessionId 传递给客户端浏览器,浏览器将这个 SessionId 保存在内存中,以后浏览器每次请求都会额外加上这个参数值,服务器根据这个 SessionId,就能取得客户端的数据信息。浏览器关闭后这个 SessionId 就会被清掉,它不会存在于用户的 Cookie 临时文件。如果客户端浏览器意外关闭,服务器保存的 Session 数据不是立即释放,此时数据还存在,只要我们知道那个 SessionId,就可以继续通过请求获得此 Session 的信息,因为此时后台的 Session 还存在,当然我们可以设置一个 Session 超时时间,一旦超过规定时间没有客户端请求时,服务器就会清除对应 SessionId 的 Session 信息。
-
明文
HTTP协议还有一个特点是明文传输,明文是指在传输阶段报文不使用二进制数据,而是使用可直接阅读的文本形式,相对 TCP 这样的二进制协议优点是可以不使用外部工具直接抓包(浏览器的network)调试,缺点是不安全,可以被监听和篡改。
14. 报文
什么是报文
报文就是HTTP协议交互中传递的信息,就是一堆参数和声明,报文本身是多行结构的字符串文本,客户端发送给服务端的叫请求报文,服务端下发给客户端的叫响应报文。报文由四部分组成分别是 起始行、头部字段、空行、主体,在请求报文中起始行又叫请求行,在响应报文中起始行又叫状态行。
请求报文
请求报文由四部分构成分别是 请求行、头部字段、空行、主体,其中 请求行、头部字段 合起来就是我们常说的请求头(Req Header),http协议规定每次请求必须发送请求头,请求主体(body)则可有可无,而空行就是用来分割请求头和请求体的。
-
请求行 请求行说明了本次请求要做什么,在请求行中定义了 请求方法、请求地址、HTTP版本。
-
头部字段 头部字段以 key-value 的形式存在,最后以换行结束。头部字段是可扩展的,可以自定义新的字段名称,名称大小写均可,通常情况下只大写首字母。如果定义了重复的字段名称只会保留一个,值会被后面的覆盖。HTTP协议并没有对头部字段的整体长度做限制,但是在服务端实践中长度超过某一个额定值4K或8K处于安全考虑会主动抛出一个错误。
头部字段的标头分为四种分别是 通用标头、请求标头、响应标头 和 实体标头,这个先放在后面讲。 -
空行
分割请求头和请求体,告诉服务端下面的内容是请求体。 -
主体
响应报文
响应报文由四部分组成分别是 状态行、头部字段、空行、主体,其中 状态行、头部字段 合起来就是响应头(Res Header)。
-
状态行
状态行说明本次请求的结果是什么,在状态行中定义了 HTTP版本、状态码、以及“短语消息”,短语消息为状态码提供了文本形式的解释,状态码和短语消息是一一对应的,比如状态码200就对应着OK。 -
头部字段
参考请求报文的头部字段 -
空行
分割响应头和响应体,告诉客户端下面的内容是响应体。 -
主体
头部字段
头部字段分为以下五类,分别是 通用头部、请求头部、响应头部、实体头部、扩展头部。
-
通用头部: 在请求头和响应头中都适用,比如 Content-Type 字段。
头部字段key 可选值 说明 Connection keep-alive、close 是否持久性连接,决定当前事务(一次三次握手和四次挥手)完成后,是否会关闭网络连接。 Date 表示报文创建时间 Transfer-Encoding chunked 告知接收端为了保证报文的可靠传输,对报文采用了什么编码方式 Cache-Control 控制缓存行为 Via 代理服务器相关信息
-
请求头部: 只能出现在请求报文中,如 Origin 字段。
头部字段key 可选值 说明 Host 接收请求的服务端的域名(或者IP)和端口 User-Agent 客户端信息,web常见的是浏览器内核以及版本 Accept application/json 等 告诉服务端期望接收的数据类型 Accept-Language zh-CN 等 告诉服务端期望接收的语言类型 Accept-Encoding gzip 告诉服务端期望接收的编码方式 Accept-Charset 告诉服务端期望接收的字符集 Authorization 客户端提供给服务器的验证数据,客户端token通常会写到Authorization字段里。 Cookie 携带Cookie Referer 客户端发起请求的地址
-
响应头部: 只能出现在响应报文中,如 Server 字段。
头部字段key 可选值 说明 Set-Cookie 服务器主动在客户端设置一个标识令牌,会自动写入Cookie。 Access-Control-Allow-Origin 指定域名 或 * 告诉客户端允许那些来源的域进行资源访问 Keep-Alive timeout=8, max=3 timeout:保持持续连接状态的最短时间,max:单个连接的最大请求数。 Server 服务端信息
-
实体头部: 用来描述报文主体的头部字段,比如 Content-Length 字段,要注意的是请求和响应报文中都有可能包含实体部分,所以这两种类型的报文都有可能出现实体头部。
头部字段key 可选值 说明 Content-Type application/json 发送的主体对象(body)类型 Content-Encoding gzip 发送的编码 Content-Language zh-CN 发送的语言 Content-Length 100{Number} 发送实体的长度,以字节为单位。
- 扩展头部: 并非规定的标准头部字段,是开发者自行定义的头部字段。
15.Content-Type 和 Accept 的区别
application/json 表示json数据格式,同时是 Content-Type 和 Accept 字段的值,他俩的区别在于 Content-Type 是实体头部,会出现在请求头和响应头表示当前传输的数据体是json格式;Accept 是请求头部,表示本次请求客户端期望服务端返回json格式数据。
16.请求url
以 http://www.baidu.com:80/assets/public/index.html?a=1&b+2#/path/main
为例来分析一下请求url的组成:
http://
: 告知浏览器当前使用的版本,大部分情况是HTTP协议,或者更为安全的HTTPS协议。
www.baidu.com
: 域名用来定位到某一台机器,向这台机器发起请求,当然域名可以替换成IP地址,但是直接使用IP在生产环境并不常见。
:80
: 端口也是必须的,IP用来定位到机器,而端口是用来确定向该机器上那个server发起请求。HTTP默认端口为80,HTTPS为443,80和443可以省略不写其他端口必须要在请求地址上体现出来。
/assets/public/index.html
: 资源路径以端口后面的第一个/开始,到?号结束,中间的/代表了层级关系。
?a=1&b+2
: 从 ? 到 # 之间的是参数,GET请求的参数会直接带在URL上,POST请求参数则在请求体中。
#/path/main
: #开始为前端的路由,路由改变页面不会刷新,以此实现前端的单页面应用,路由是不会传到服务端的。
17.状态码
响应报文的状态行声明了本次请求的状态码,不同状态码表示的含义如下。
状态码 | 说明 |
---|---|
1xx | 表示请求已经接收,正在继续处理。 |
200 | 成功响应 |
204 | 请求处理成功,但是没有资源可以返回 |
206 | 对资源某一部分进行响应,由Content-Range 指定范围的实体内容。 |
301 | 永久性重定向,请求的资源已经重新分配 URI,以后应该使用资源现有的 URI |
302 | 临时性重定向。请求的资源已被分配了新的 URI,希望用户(本次)能使用新的 URI 访问。 |
303 | 由于请求对应的资源存在着另一个 URI,应使用 GET 方法定向获取请求的资源。 |
304 | 客户端发送附带条件的请求时,服务器端允许请求访问资源,但未满足条件的情况。 |
307 | 临时重定向。该状态码与 302 Found 有着相同的含义。 |
400 | 请求报文中存在语法错误。当错误发生时,需修改请求的内容后再次发送请求。 |
401 | 请求未经授权 |
403 | 该状态码表明对请求资源的访问被服务器拒绝了。 |
404 | 该状态码表明服务器上无法找到请求的资源。 |
500 | 该状态码表明服务器端在执行请求时发生了错误。 |
503 | 该状态码表明服务器暂时处于超负载或正在进行停机维护,现在无法处理请求。 |
总的来说 1xx 是进行中,2xx 是成功,3xx 是重定向,4xx 是客户端错误,5xx 是服务端错误。
请求方法
18.常用请求方法
- GET,从服务器上获取资源,无主体。
- POST,向服务器发送数据(常见的场景是表单提交)有主体。
- DELETE,从服务器上删除资源,无主体。
- PUT,更新资源,有主体。
- HEAD,获得响应首部,HEAD 方法和 GET 方法一样,只是不返回报文主体部分。用于确认URI有效性及资源更新时间等。
- OPTIONS,前置请求,询问支持的方法。
- TRACE,追踪路径,TRACE 方法是让 Web 服务器端将之前的请求通信环回给客户端的方法。
- CONNECT,用隧道协议连接代理,CONNECT方法要求在与代理服务器通信时建立隧道,实现用隧道协议进行 TCP 通信。主要用于 SSL(Secure Sockets Layer,安全套接层)和 TLS(Transport Layer Security,传输层安全)协议把通信内容加密后经网络隧道传输。
19.GET 和 POST 的区别
1)上面的请求方法常用的只有GET和POST,其他方法基本用不到,在工作中更新和删除并不会特意用DELETE和PUT方法,而是统一用POST来解决。POST和GET在使用上有一些区别我们先直接给出来。
- 常规在数据获取(查)时用GET方式,在数据提交(增删改)时使用POST方式。
- 相对GET而言POST安全性更好,因为参数在地址栏直接不可见。(HTTP本身是明文传输POST抓包参数也可查看)
- GET在URL中的参数有长度限制2kb(实测了一下好像没限制),而POST没有此限制可用来传输文件。
- GET参数通过URL传递,POST放在RequestBody中。(在web中GET请求本身没有ReqBody)
- POST方法通过RequestBody可以传递json数据更加语义化。(对有层级的数据用json描述体验更好)
- GET请求性能更好速度更快
- GET请求是幂等的
2) 当直接在地址栏(非ajax)访问GET地址时还有下面这些特点:
- GET在浏览器回退时是无害的(被缓存),而POST会再次提交请求。
- GET产生的URL地址可以被浏览器收藏,而POST不可以。
- GET请求会被浏览器主动缓存,而POST不会,除非手动设置。
- GET请求只能进行URL编码,而POST支持多种编码方式。
- GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。
- 对参数的数据类型,GET只接受ASCII字符,而POST没有限制。
这些特点其实只在web领域适用,如果说的更贴切一些就是只在浏览器适用,HTTP不只是在浏览器端使用,抛开web上面的几条区别就需要重新理解了。GET和POST是HTTP定义的Method,HTTP传输依赖TCP,在TCP这一层并没有GET和POST相关的标准,所以GET和POST本质上只是语义和规范上的区别。
3)GET在url中传参且长度小于2kb POST通过ReqBody传参
GET在url中传参且长度小于2kb(实测了一下好像没限制)在浏览器中是没问题的,因为浏览器厂商为了符合规范和语义对GET请求做了限制只允许通过url传参,至于2kb的限制是因为浏览器为了避免url过长影响传输效率对地址栏做了限制。上文有提到过url上除了#号之后的路由其他部分都可以传到服务端,当然也包括?号后面的query参数,这和请求方法无关,数据既然可以抵达服务端那只要做了解析就可以读取,所以POST请求通过url也可以传参。我们在讨论GET和POST时不应该只局限在浏览器(HTTP是跨平台的),抛开浏览器GET请求其实也可以用ReqBody来传参,下面截图通过node+axios做了演示。结论就是GET请求虽然可以通过ReqBody传参,但是规范上并不推荐这么做,各个浏览器厂商、各种服务器、第三方框架针对该规范可能会做不同的实现,不保证可用性与稳定性。但在技术上GET和POST都是基于TCP的传输实现,没有本质区别,完全可以实现GET通过ReqBody传参,POST通过url传参。
4)GET获取数据POST提交数据
既然GET和POST用URL和ReqBody都可以传参,那么GET获取数据POST提交数据的设定也不是必须的,如果你愿意完全可以反过来用,差别只在语义上。
5)相对GET而言POST安全性更好
这里的安全只是因为POST请求参数在URL上不可见,但说到安全往往和攻防挂钩,HTTP本身是明文传输POST请求随便抓个包或者在network也可以看到详细的参数。
6)GET请求性能更好速度更快
GET在请求时只发送一个数据包,会将header和data一起发送到服务端,而POST会发送两个数据包先发送header,服务器返回100,然后再发送data,服务器返回200。返回状态码100这个过程在浏览器network是不可见的,通过 (new XMLHttpRequest()).onreadystatechange = e => console.log(ajax.status)
可以看到100的过程。GET只发一个数据包以及对url长度的限制,所以性能好与POST。(GET只发一个数据包和浏览器实现也有关系部分浏览器也会和POST一样发两个包)
7)GET请求是幂等的
幂等是指多次请求同一个接口返回数据应该保持一致(不改变服务器状态),可以重复发送请求,POST增加数据时重复发送会带来不可预料的后果。
20.如何优化HTTP请求
web性能优化最主要的就是要减少HTTP请求及每次响应中内容的长度:
- 域名解析:尽可能减少域名解析次数-----减少跨站、外部资源的引用
- 创建连接:减少连接创建次数-----使用Keep-Alive避免重复连接
- 发送请求:尽力减少请求次数-----合理设置Expires时间、资源合并
- 等待响应:提高服务器端运行速度-----提高数据运算及查询速度
- 接收响应:尽可能减少响应数据长度-----启用压缩
21.什么是CDN
CDN的全称是Content Delivery Network,即内容分发网络,它应用了 HTTP 协议里的缓存和代理技术,代替源站响应客户端的请求。CDN 是构建在现有网络基础之上的网络,它依靠部署在各地的边缘服务器,通过中心平台的负载均衡、内容分发、调度等功能模块,使用户就近获取所需内容,降低网络拥塞,提高用户访问响应速度和命中率。CDN的关键技术主要有内容存储和分发技术。
22.什么是HTTTPS
HTTP 是明文传输,很容易被攻击者窃取重要信息,鉴于此,HTTPS 应运而生。HTTPS 的全称为 (Hyper Text Transfer Protocol over SecureSocket Layer),HTTPS 和 HTTP 有很大的不同在于 HTTPS 是以安全为目标的 HTTP 通道,在 HTTP 的基础上通过传输加密和身份认证保证了传输过程的安全性。HTTPS 在 HTTP 的基础上增加了 SSL 层,也就是说 HTTPS = HTTP + SSL。
总结
大佬就是大佬,每一个问题和答案总结的很到位,很感谢大佬的投稿分享。
当然光刷HTTP面试题肯定是不够的,所以小编也为大家准备了其它学习资料的大礼包,戳这里免费领取,暗号:CSDN。
获取方式:戳这里免费领取,暗号:CSDN