众所周知,计算机网络作为计算机中的一大巨头,每年面试的时候都会被问的很多,同时,作为计算机网络中最为基础的协议——HTTP协议,在面试中被问的概率是很高的。无论是面试开发岗还是安全岗,清楚的了解HTTP协议的工作流程是必不可少的,下面就将围绕几个比较常见的关于HTTP协议的面试题做出收集和知识点整理
HTTP基本概念
HTTP是什么?
HTTP是超文本传输协议,也就是Hyper Text Transfer Protocol。
如何理解超文本传输协议?
HTTP的名字超文本传输协议可以拆成三个部分:超文本、传输、协议
协议:HTTP是一个用在计算机世界的协议。它使用计算机能够理解的语言确立了一种计算机之间的交流通信的规范,以及相关的各种控制和错误处理方式 传输:HTTP协议是一个双向协议,是一个在计算机世界里专门用来在两点之间传输数据的约定和规范 超文本:先来理解简单额文本,互联网早期的时候只是简单的字符文字,但现在文本的涵义已经可以扩展为图片、视频、压缩包等,但是在HTTP眼中这些都只算作文本;再来理解超文本,它就是超越了普通文本的文本,它是文字、图片、视频的混合体,且含有超链接,能从一个超文本跳转到另一个超文本;HTML就是最常见的超文本,本身是纯文本文件,但是内部用很多标签定义了图片、视频等的链接,再经过浏览器的解释,呈现给我们的就是一个有文字、有画面的网页了
综上所述,HTTP是一个在计算机世界里专门在两点之间传输文字、图片、音频、视频等超文本数据的约定和规范,HTTP可以在服务器和服务器之间进行传输(不一定是服务器和本地浏览器)
HTTP常见的状态码有哪些?
1xx:提示信息,是协议处理中的一种中间状态,实际用到的比较少
2xx:表示服务器已经成功处理了客户端的请求,这是我们最希望看到的,比如喜闻乐见的200状态码
-
200 OK 是最常见的成功状态码,表示一切正常。如果是非HEAD请求,服务器返回的响应头都会有body数据。
-
204 No Content 也是最常见的成功状态码,与200 OK基本相同,但响应头没有body数据
-
206 Partial Content 是应用于HTTP分块下载或断点续传,表示响应返回的body数据并不是资源的全部,而是其中的一部分,也是服务器处理成功的状态
3xx:表示客户端请求的资源发生了变动,需要客户端用新的URL重新发送请求获取资源
-
301 Moved Permanently 表示永久重定向,说明请求的资源已经不存在,需要改用新的URL再次访问
-
302 Found 表示临时重定向,说明请求的资源还在,但是要用另一个URL来访问
-
304 Not Modified 不具有跳转的含义,表示资源未修改,重定向已存在的缓冲文件,也叫做缓冲重定向,也就是告诉客户端可以继续使用缓存资源,用于缓存控制
其中,301和302后面都会跟着一个Location字段,指明后续要跳转的URL,浏览器会自动重定向新的URL
4xx 表示客户端发送的报文有误,服务器无法处理
-
400 Bad Request 表示客户端请求的报文有错误,但只是一个笼统的错误
-
403 Forbidden 表示服务器禁止访问资源,并不是客户端的请求出错,只是服务器不允许查看这部分资源
-
404 Not Found 表示请求的资源在服务器上不存在或者未找到,所以无法提供给客户端
5xx 表示客户端请求报文正确,但是服务器处理时内部发生了错误,属于服务端的错误码
-
500 Internal Server Error与 400 类型相似,是个笼统通⽤的错误码,服务器发⽣了什么错误,我们并不知道
-
501 Not Implemented 表示客户端请求的功能还不⽀持,类似“即将开业,敬请期待”的意思
-
502 Bad Gateway 通常是服务器作为⽹关或代理时返回的错误码,表示服务器⾃身⼯作正常,访问后端服务器发⽣了错误
-
503 Service Unavailable 表示服务器当前很忙,暂时⽆法响应客户端,类似“⽹络服务正忙,请稍后重试”的意思
HTTP常见字段有哪些?
HOST字段:客户端发送请求时,用来指定服务器的域名
例如,当客户想要访问A网站时,其HOST字段为
HOST:www.A.com
有了HOST字段,就可以将请求发往同一台服务器上的不同网站
Content-Length字段:服务器在返回数据时,会有Content-Length字段,表明本次回应的数据长度,例如,当资源大小为1000字节时,实际上就是在告诉浏览器,本次服务器回应的数据长度是1000字节,后面的字节属于下一次回应
Content-Length:1000
由于HTTP是基于TCP传输协议进行通信的,使用TCP传输协议,就会存在“粘包”的问题,HTTP协议通过设置回车符、换行符作为HTTP头部的边界,通过Content-Length字段作为HTTP主体的边界,这两个方式都是为了解决“粘包”的问题
Connection字段:常用于客户端要求使用HTTP持续链接机制,以便减少TCP连接次数,方便其他请求复用;HTTP持续链接的意思是只要任意一端没有明确提出断开连接,则保持TCP的连接状态
HTTP/1.1版本的默认连接是持续连接,但是为了兼容老版本的HTTP,需要指定Connection首部字段为 Keep-Alive
Connection:Keep-Alive
如果要关闭,则改为如下
Connection:close
注意和TCP中的Keepalive区分开来,TCP的Keep alive也叫TCP的保活机制该功能是由内核实现的当客户端和长达一定时间没有进行数据交互时,内核为了确定该连接是否还有效,就会发送探测报文,来检测对方是否还在线,然后决定是否要关闭连接
Content-Type字段:用于服务器回应时,告诉客户端,本次数据是什么格式
Content-Type:text/html;Charset=utf-8
上面的类型表示,发送的是网页,而且编码是UTF-8
客户端请求的时候,可以使用Accept字段表明自己可以接收哪些数据格式
Accept:*/*
上面代码表示客户端可以接收任何格式的数据
Content-Encoding字段:表明数据的压缩方式,表示服务器返回的数据使用了什么压缩格式
Content-Encoding:gzip
表示服务器返回了采用gzip压缩的数据,告知客户端要用此方法解压,客户端在请求的时候,用Accept-Encoding字段说明自己可以接受哪些压缩方法
Accept-Encoding:gzip,deflate
GET和POST
GET和POST方法是安全和幂等的吗?
先来解释一下安全和幂等是什么:
-
在HTTP协议中,所谓的安全就是指请求方法不会破坏服务器上的资源
-
所谓的幂等,就是指执行相同的操作,结果都是相同的
所以根据定义,GET方法是安全且幂等的,因为是只读操作,无论操作多少次,服务器上的数据都是安全的,且每次结果都是相同的。所以,可以对GET请求的数据进行缓存处理,这个缓存可以放到浏览器本身上,也可以放到代理上(如nginx),而且在浏览器中GET请求可以保存为书签
POST因为是新增或者提交数据的操作,会修改服务器上的资源,所以是不安全的,且多次提交数据会创建多个资源,所以不是幂等的,浏览器一般也不会缓存POST请求
但是在实际过程中,开发者不一定会按照RFC规定的语义来实现GET和POST方法,我们既可以用GET方法来实现新增或者删除数据的请求,这样的GET方法自然不是安全和幂等的;我们也可以用POST方法来实现查询数据的请求,这样的POST方法自然就是安全和幂等的
所谓GET是安全的POST是不安全的是在服务器的角度来说,如果站在数据是否会被泄露的角度来说,GET不比POST安全,因为GET使用url进行传输,而POST使用body数据进行传播,GET数据比POST数据更容易看见,但是也不能说POST就比GET安全,因为抓个包也能看到POST的body数据
所以要避免传输过程中数据被窃取,就要使用HTTPS协议,这样所有的HTTP数据都会被加密传输,不容易受到中间人攻击
HTTP的缓存技术
HTTP的缓存技术有哪些实现方式?
对于一些重复性的HTTP请求,我们可以把这些请求-响应的数据都缓存在本地,那么下次就直接读取本地的数据,不必再通过网络获取服务器的响应了,这样的话会对性能有肉眼可见的提升
HTTP的缓存方式有两种实现方式,分别是强制缓存和协商缓存
什么是强制缓存?
强制缓存指的是只要浏览器判断缓存没过期,则直接使用浏览器本地缓存,决定权在本地浏览器上
强制缓存是使用下面两个HTTP响应头部字段实现的,他们都用来表示资源在客户端缓存的有效期:
Cache-Control,是一个相对时间 Expires,是一个绝对时间
当两个同时拥有时,Cache-Control的优先级高于Expires,具体实现流程如下:
-
当浏览器第一次请求访问服务器资源的时候,服务器会在返回这个资源的同时,在Response头部加上Cache-Control,Cache-Control中设置了过期时间大小;
-
浏览器再次请求访问该服务器的该资源时,会通过请求资源的时间与Cache-Control中设置的过期时间的大小,来计算出该资源是否过期,如果没有,则继续使用该缓存,否则重新请求服务器
-
服务器再次接收到请求后,会更新Resposnse头部的Cache-Control
什么是协商缓存?
这个时候状态码304发挥了作用,状态码304是服务器告知浏览器可以使用本地缓存的资源,通常这种通过服务端告知客户端是否可以使用缓存的方式被称为协商缓存
上图就是一个协商缓存的过程,所以协商缓存就是与服务端协商之后,通过协商结果来判断是否使用本地缓存,协商缓存通过两种头部来实现
第一种:请求头部中的If-Modified-Since字段与响应头部中的Last-Modified字段实现 响应头部中的Last-Modified:表示这个资源的最后修改时间 请求头部中的If-Modified-Since:当资源过期了,发现响应头部中具有Last-Modified声明,则再次发起请求的时候带上Last—Modified的时间,服务器收到请求后发现有If-Modified-Since则与被请求资源的修改时间进行对比(Last-Modified),如果最后修改时间较大,说明资源被修改过,则返回最新资源,如果修改时间较小,则说明资源无新修改,响应304,使用跳转缓存 第二种:请求头部中的If-None-Match字段与响应头部中的Etag 这两个字段的意思是: 响应头部中的Etag:唯一标识响应资源; 请求头部中的If-None-Match:当资源过期时,浏览器发现响应头里有Etag,则再次向服务器发起请求时,会将请求头If-None-Match值设置为Etag的值,服务器收到请求后进行对比,如果资源没有发生变化则返回304,如果发生了变化则返回200
第一种实现方法基于时间实现,第二种方法基于一个唯一标识实现的,相对来说后者可以更加准确的判断文件内容是否被修改,避免由于时间篡改而导致的不可靠问题,所以,当Etag字段和If-Modified-Since字段都存在的时候,Etag的优先级更高,下图是协商缓存的工作示意图