本人其实对HTTP了解的不是太深,学习HTTP仅仅通过相关的面试问题进行了解,现在做一个整理,希望能够有所深层次的思考
HTTP协议的版本
HTTP
(HyperText Transfer Protocol
)协议是基于TCP
的应用层协议,它不关心数据传输的细节,主要是用来规定客户端和服务端的数据传输格式,最初是用来向客户端传输HTML
页面的内容。默认端口是80
。
主要说明一下HTTP1.0
HTTP1.1
HTTP2.0
版本,说明这个问题主要可以回答四个问题。
HTTP协议有什么特点 ?
- 简单快速:每个资源(比如图片、页面)都通过
url
来定位。这都是固定的,在http
协议中,处理起来也比较简单,想访问什么资源,直接输入url
即可。 - 灵活:
http
协议的头部有一个数据类型
,通过http协议
,就可以完成不同数据类型的传输。 - 无连接:连接一次,就会断开,不会继续保持连接。(这个特性针对
HTTP1.0
版本) - 无状态:客户端和服务器端是两种身份。第一次请求结束后,就断开了,第二次请求时,服务器端并没有记住之前的状态,也就是说,服务器端无法区分客户端是否为同一个人、同一个身份。(服务端总是被动的,这一点问题在
HTTP2.0
版本得到了解决)
什么是持久连接/HTTP长连接 ?
- 轮询:
http1.0
中,客户端每隔很短的时间,都会对服务器发出请求,查看是否有新的消息,只要轮询速度足够快,例如1秒
,就能给人造成交互是实时进行的印象。这种做法是无奈之举,实际上对服务器、客户端双方都造成了大量的性能浪费。 - 长连接:
HTTP1.1
中,通过使用Connection:keep-alive
进行长连接。客户端只请求一次
,但是服务器会将继续保持连接,当再次请求时,避免了重新建立连接。
注意
,HTTP 1.1
默认进行持久连接。在一次 TCP 连接中可以完成多个 HTTP 请求,但是对每个请求仍然要单独发 header
,Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间。
说到长连接就不得不提到长连接的管线化
问题。
- 管线化的原理:长连接时,默认的请求这样的:
请求1 --> 响应1 -->请求2 --> 响应2 --> 请求3 --> 响应3
- 管线化就是,把现在的请求打包,
客户端一次性发过去,服务端也给一次响应回来
。
关于HTTP2.0
你知道多少 ?
-
HTTP/2
引入了"服务端推(server push)"
的概念,它允许服务端在客户端需要数据之前就主动地将数据发送到客户端缓存中,从而提高性能。 -
HTTP/2
提供更多的加密支持 -
HTTP/2
使用多路技术,允许多个消息在一个连接上同时交差。 - 它增加了头压缩(
header compression
),因此即使非常小的请求,其请求和响应的header
都只会占用很小比例的带宽
HTTP
和HTTPS
?
-
HTTP
协议通常承载于TCP
协议之上,在HTTP
和TCP
之间添加一个安全协议层(SSL或TSL)
,这个时候,就成了HTTPS
- 默认
HTTP
的端口号为80
,HTTPS
的端口号为443
既然有了HTTP协议,为什么要有HTTPS,因为HTTPS更加的安全,那为什么HTTPS安全
因为网络请求需要中间有很多的服务器路由器的转发。中间的节点都可能篡改信息,而如果使用HTTPS
,密钥
在你和终点站才有。https之所以比http安全,是因为它利用ssl/tls
协议传输。它包含证书,卸载,流量转发,负载均衡,页面适配,浏览器适配,refer传递等。保障了传输过程的安全性
HTTP报文
这是一个很大的问题,这个问题不复杂就是麻烦,但是这个很重要。说明报文问题之前,先描述一下报文会在哪里用到,在用户输入URL时,会用到报文。
一个页面从输入 URL 到页面加载显示完成,这个过程中都发生了什么 ?
- 浏览器查找域名对应的IP地址(DNS 查询:浏览器缓存->系统缓存->路由器缓存->ISP DNS 缓存->根域名服务器)
- 浏览器向 Web 服务器发送一个 HTTP 请求(TCP三次握手)---这里用到了请求报文
- 服务器
301
重定向(从 http://example.com 重定向到 http://www.example.com) - 浏览器跟踪重定向地址,请求另一个带 www 的网址
- 服务器处理请求(通过路由读取资源)
- 服务器返回一个 HTTP 响应(报头中把 Content-type 设置为 'text/html')---这里用到了响应报文
- 浏览器根据响应提进行
DOM
树构建 - 浏览器发送请求获取嵌在 HTML 中的资源(如图片、音频、视频、CSS、JS等)
- 浏览器显示完成页面
- 浏览器发送异步请求
HTTP请求报文
连接成功建立后,开始向web服务器发送请求,当浏览器向Web服务器发出请求时,它向服务器传递了一个数据块,也就是请求报文,HTTP请求报文由4部分组成:
- 起始行:HTTP请求方法 URL HTTP版本
- 请求头:请求头的形式通过一个键值对进行渲染
- 空行:当服务器在解析请求头的时候,如果遇到了空行,则表明,后面的内容是请求体
- 请求体:get方法的请求体是没有内容的(放在了url里) post方法的请求体包含请求的内容
下面是一个HTTP请求的例子:
GET /sample.jsp HTTP/1.1
Accept:image/gif.image/jpeg,*/*
Accept-Language:zh-cn
Connection:Keep-Alive
Host:localhost
User-Agent:Mozila/4.0(compatible;MSIE5.01;Window NT5.0)
Accept-Encoding:gzip,deflate
username=jinqiao&password=123412345678
起始行
- 请求的起始行是:”
方法 URL http版本
“GET /sample.jsp HTTP/1.1
- 根据HTTP标准,HTTP请求可以使用多种请求方法。例如:HTTP1.1支持7种请求方法:
GET、POST、HEAD、OPTIONS、PUT、DELETE和TARCE
。在Internet应用中,最常用的方法是GET
和POST
。 -
URL
完整地指定了要访问的网络资源,通常只要给出相对于服务器的根目录的相对目录
即可,因此总是以“/”
开头。 - 协议版本声明了通信过程中使用HTTP的版本。
请求头(Request Header)
说明:常用的请求头和响应头,请看下面文章: https://blog.csdn.net/qq_3055...
请求头包含许多有关的客户端环境和请求正文的有用信息。例如,请求头可以声明浏览器所用的语言,请求正文的长度等。
# host表示主机名,User-Agent表示用户代理即浏览器
Accept:image/gif.image/jpeg.*/*
Accept-Language:zh-cn
Connection:Keep-Alive
Host:localhost
User-Agent:Mozila/4.0(compatible:MSIE5.01:Windows NT5.0)
Accept-Encoding:gzip,deflate.123456
请求正文
请求头和请求正文之间是一个空行,这个行非常重要,它表示请求头已经结束,接下来的是请求正文。请求正文中可以包含客户提交的查询字符串信息:
username=frewen&password=12341
HTTP响应
响应 web服务器收到这个请求,进行处理。从它的文档空间中搜索子目录mydir
的文件index.html
。如果找到该文件,Web服务器把该文件内容传送给相应的Web浏览器。为了告知浏览器,Web服务器首先传送一些HTTP头信息,然后传送具体内容(即HTTP体信息),HTTP头信息和HTTP体信息之间用一个空行分开。
HTTP响应与HTTP请求相似,HTTP响应也由4个部分构成,分别是:
- 起始行:HTTP协议版本 响应状态码 响应状态信息
- 响应头(Response Header) :通过键值对的形式进行表示
- 空行:当客户端在解析响应头的时候,如果遇到了空行,则表明,后面的内容是响应体
- 响应体: 网页代码 HTML、CSS、JS代码文件
下面是一个HTTP响应的例子:
HTTP/1.1 200 OK
Server:Apache Tomcat/5.0.12
Date:Mon,6Oct2003 13:23:42 GMT
Content-Length:112
HTTP响应示例
Hello HTTP!
协议状态代码描述HTTP响应的第一行类似于HTTP请求的第一行,它表示通信所用的协议是HTTP1.1服务器已经成功的处理了客户端发出的请求(200表示成功): HTTP/1.1 200 OK
响应头(Response Header)响应头也和请求头一样包含许多有用的信息,例如服务器类型、日期时间、内容类型和长度等:
Server:Apache Tomcat/5.0.12
Date:Mon,6Oct2003 13:13:33 GMT
Content-Type:text/html
Last-Moified:Mon,6 Oct 2003 13:23:42 GMT
Content-Length:11212345
响应体就是服务器返回的HTML页面:
HTTP响应示例
Hello HTTP!
HTTP状态码
HTTP应答码由3位数字构成,其中首位数字定义了应答码的类型:
-
1XX
-信息类(Information),表示收到Web浏览器请求,正在进一步的处理中 -
2XX
-成功类(Successful),表示用户请求被正确接收,理解和处理例如:200 OK -
3XX
- 重定向类(Redirection),表示请求没有成功,客户必须采取进一步的动作。 -
4XX
- 客户端错误(Client Error),表示客户端提交的请求有错误 例如:404 NOT Found,意味着请求中所引用的文档不存在。 -
5XX
- 服务器错误(Server Error)表示服务器不能完成对请求的处理:如 500
常见的状态码
100 Continue 继续,一般在发送post请求时,已发送了http header之后服务端将返回此信息,表示确认,之后发送具体参数信息
200 OK 正常返回信息
201 Created 请求成功并且服务器创建了新的资源
202 Accepted 服务器已接受请求,但尚未处理
206 Partial Content:客户端发送一个带有range头的get请求,服务端完成它。206的应用的场景:range指的是请求的范围,客户端只请求某个大文件里的一部分内容。比如说,如果播放视频地址或音频地址的前面一部分,可以用到206。
301 Moved Permanently 请求的网页已永久移动到新位置。(永久重定向)
302 Found 临时性重定向。
303 See Other 临时性重定向,且总是使用 GET 请求新的 URI。
304 Not Modified 自从上次请求后,请求的网页未修改过。(服务器告诉客户端,客户端已经有缓存了,不需要从服务器这里取了。)
400 Bad Request 客户端有语法错误,不能被服务器所理解
401 Unauthorized 请求未授权。
403 Forbidden 禁止访问。
404 Not Found 找不到如何与 URI 相匹配的资源。
500 Internal Server Error 最常见的服务器端错误。
503 Service Unavailable 服务器端暂时无法处理请求(可能是过载或维护)。
提到上面的状态码,不得不提到304
缓存问题:304缓存的原理
- 服务器首先产生ETag,服务器可在稍后使用它来判断页面是否已经被修改。本质上,客户端通过将该记号传回服务器要求服务器验证其(客户端)缓存
- 304是HTTP状态码,服务器用来标识这个文件没修改,不返回内容,浏览器在接收到个状态码后,会使用浏览器已缓存的文件
- 客户端请求一个页面(A)。 服务器返回页面A,并在给A加上一个ETag。 客户端展现该页面,并将页面连同ETag一起缓存。 客户再次请求页面A,并将上次请求时服务器返回的ETag一起传递给服务器。 服务器检查该ETag,并判断出该页面自上次客户端请求之后还未被修改,直接返回响应304(未修改——Not Modified)和一个空的响应体
HTTP方法
HTTP
方法主要包括以下几个:
-
GET
:获取资源 -
POST
:传输资源 -
PUT
:更新资源 -
DELETE
:删除资源 -
HEAD
:获得报文首部
说明一下get
和post
的区别
- 浏览器在回退时,
get
不会重新请求,但是post
会重新请求。【重要】 -
get
请求会被浏览器主动缓存,而post
不会。【重要】 -
get
请求的参数,会报保留在浏览器的历史记录里,而post
不会。做业务时要注意。为了防止CSRF
攻击,很多公司把get
统一改成了post
。 -
get
请求在url
中传递的参数有大小限制,基本是2kb
,不同的浏览器略有不同。而post没有注意。 -
get
的参数是直接暴露在url
上的,相对不安全。而post
是放在请求体中的。