HTTP协议
HTTP(超文本传输协议,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议.
这个协议最初设计是为了提供一种发布和接受HTML页面的方法.是用于WWW服务器传输超文本到本地浏览器的传输协议.
HTTP协议定义在网络七层中的应用层,通过传输层的TCP协议进行传输,因为HTTP协议需要建立连接,所以使用TCP协议不使用UDP协议.
为了避免每次请求的都经历握手带来的延迟,应用层会选择不同策略的http长链接方案
HTTP1.0
HTTP 协议老的标准是HTTP/1.0,为了提高系统的效率,HTTP 1.0规定浏览器与服务器只保持短暂的连接,浏览器的每次请求都需要与服务器建立一个TCP连接,服务器完成请求处理后立即断开TCP连接,服务器不跟踪每个客户也不记录过去的请求。
但是这样就带来了两个问题连接无法复用和排头阻塞
连接无法复用
因为每次连接都需要通过TCP的三次握手和慢启动,三次握手在高延迟的情况下影响严重,慢启动在传输大文件类请求影响较大
排头阻塞
在缓存式通信网络交换中FIFO(先进先出)队列,所以可能出现垃圾请求影响健康请求.
HTTP1.1
为了解决HTTP1.0的设计缺陷,HTTP1.1默认使用带流水线的持久连接,在一个TCP连接下,可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟.
HTTP1.1还允许客户端不用等待上一次请求返回就可以发出下一回请求,但是服务端必须按照请求的顺序依次返回响应结果,以保证客户端可以区分出请求相应的内容.
HTTP1.1与1.0的区别
**长连接
HTTP 1.1支持长连接(PersistentConnection)和请求的流水线(Pipelining)处理,在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟,在HTTP1.1中默认开启Connection: keep-alive,一定程度上弥补了HTTP1.0每次请求都要创建连接的缺点。
缓存处理
在HTTP1.0中主要使用header里的If-Modified-Since,Expires来做为缓存判断的标准,HTTP1.1则引入了更多的缓存控制策略例如Entity tag,If-Unmodified-Since, If-Match, If-None-Match等更多可供选择的缓存头来控制缓存策略。
带宽优化及网络连接的使用
HTTP1.0中,存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,并且不支持断点续传功能,HTTP1.1则在请求头引入了range头域,它允许只请求资源的某个部分,即返回码是206(Partial Content),这样就方便了开发者自由的选择以便于充分利用带宽和连接。
错误通知的管理
在HTTP1.1中新增了24个错误状态响应码,如409(Conflict)表示请求的资源与资源的当前状态发生冲突;410(Gone)表示服务器上的某个资源被永久性的删除。
Host头处理
在HTTP1.0中认为每台服务器都绑定一个唯一的IP地址,因此,请求消息中的URL并没有传递主机名(hostname)。但随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个IP地址。HTTP1.1的请求消息和响应消息都应支持Host头域,且请求消息中如果没有Host头域会报告一个错误(400 Bad Request)。
SPDY:HTTP1.x的优化
SPDY的出现不是用来替代HTTP的新协议,而是用来优化了HTTP1.X.
SPDY主要的优化方面如下:
降低延迟
SPDY使用了多路复用.多路复用通过多个请求共享一个TCP连接方式,解决HOL(排头阻塞)的问题,降低延迟的同时提高带宽的使用效率.
请求优先级
多路复用带来一个新问题,在共享一个连接的情况下,一个请求阻塞可能会导致关键请求被阻塞,所以SPDY给每个请求设置了优先级,这样请求就会按照优先级来进行响应.
Header压缩
SDPY中压缩请求和响应的HTTP报头,从而减少传输的数据包和字节数
服务器启动流
服务器可以分发内容到客户端,而不用客户端再去请求服务器资源.
HTTP2.0
HTTP2.0可以说是SDPY的升级版,但是跟SDPY有所不同,区别如下:
- HTTP2.0支持明文HTTP传输,但是SDPY强制使用HTTPS传输
- HTTP2.0报头压缩算法采用HPACK 并非SDPY采用的DEFLATE
HTTP2.0与HTTP1.X的区别
**多路复用
多路复用允许同时通过单一的HTTP2连接发起多重的请求-响应消息.
当HTTP1.X时针对于同一个域名下请求次数会有一定数量的限制.超过限制后请求会被阻塞,但是有了多路复用之后就可以实现多流并行
新的二进制格式
HTTP2.0在应用层和传输层之间加了一个二进制分帧层.通过将传输信息分割为更小的消息和帧,并对他们进行二进制格式的编码.
这种单连接多资源的方式,减少服务端的连接压力,内存占用更少,连接吞吐量更大.
首部压缩
HTTP/1.1并不支持 HTTP 首部压缩,为此 SPDY 和 HTTP/2 应运而生, SPDY 使用的是通用的DEFLATE 算法,而 HTTP/2 则使用了专门为首部压缩而设计的 HPACK 算法
服务器推送
服务器推送是在客户端请求之前发送数据的机制.
当一个请求是由主页发起的,那么服务器可能会响应主页的内容、样式表和图片等,因为服务器知道客户端会用这些东西. 最大的好处可以缓存,那么就可以实现共享缓存资源.
请求方法
根据HTTP标准,HTTP请求可以使用多种请求方法.
HTTP1.0定义了三种请求方法: GET, POST和HEAD 方法
HTTP1.1新增了五种请求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法
- GET 请求指定的页面信息,并返回实体主体
- HEAD 类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头
- POST 向指定资源提交数据进行处理请求(例如提交表单或者上传文件).数据被包含在请求体中.POST请求可能会导致新的资源的建立或已有资源的修改
- PUT 从客户端向服务器传送的数据取代指定的文档内容**(与POST的区别在于等幂性,PUT是等幂的,而POST是非等幂的)**
- DELETE 请求服务器删除指定的页面
- CONNECT HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器
- OPTIONS 允许客户端查看服务器的性能
- TRACE 回显服务器收到的请求,主要用于测试或诊断
- PATCH 对资源应用部分修改
GET和POST的区别
- GET请求的数据会放在URL之后,以?分割URL和传输的数据,参数之间以&相连.POST则是把数据放在HTTP的Body中
- GET提交的数据大小有限制(因为URL的长度有限制),而POST方式提交的数据没有限制
- GET方式需要使用Request.QueryString来获取变量,而POST方式通过Request.Form来获取(服务器端获取数据的方式)
- GET方式提交数据会带来安全问题,比如隐私数据会直接显示在URL中
状态码
状态码由三位数字组成,第一个数字定义了相应的类别,共分物种类别:
- 1xx : 提示信息 – 表示请求已接收,继续处理
- 2xx : 成功 – 表示请求已被成功接收,理解,接受
- 3xx : 重定向 – 要完成请求必须进行更进一步的操作
- 4xx : 客户端错误 – 请求有语法错误或请求无法实现
- 5xx : 服务器端错误 – 服务器未能实现合法的请求
常见状态码:
- 200 OK 客户端请求成功
- 302 Found 重定向,客户端对新的URL发出新的Request
- 304 Not Modified 客户端可直接使用缓存文件
- 400 Bad Request 客户端请求有语法错误,不能被服务器理解
- 403 Forbidden 服务器收到请求,但是拒绝提供服务
- 404 Not Found 请求资源不存在
- 500 Internal Server Error 服务器发生不可预期的错误
- 503 Server Unavailable 服务器当前不能处理客户端的请求,一段时间后可能恢复 正常
常用头信息
请求头
Cache头域
If-Modified-Since
作用: 把浏览器缓存页面的最后修改时间发送到服务器去,服务器会把这个时间与服务器上实际文件的最后修改时间进行对比.如果时间一致,那么返回304,客户端就直接使用本地缓存文件.如果时间不一致,就会返回200和新的文件内容.客户端接收到之后,会把新文件缓存起来,并显示在浏览器中.
If-None-Match
作用: If-None-Match和ETag一起工作,工作原理是在HTTP Response中添加ETage信息.当用户再次请求该资源时,将在请求头中加入If-None-Match信息.如果服务器验证资源的ETag没有改变,将返回一个304状态码告诉客户端使用本地缓存文件,否则将返回200和新的资源和Etag.
Pragma
作用: 防止页面被缓存 在HTTP/1.1中,它和Cache-Control:no-cache作用一模一样
Cache-Control
作用: 用来指定Response-Request遵循的缓存机制.如下:
- Cache-Control:Public 可以被任何缓存所缓存
- Cache-Control:Private 内容只缓存到私有缓存中
- Cache-Control:no-cache 所有内容都不会被缓存
Client头域
Accept
作用: 浏览器/客户端告诉服务器自己接受的介质类型(即Content-Type), **/*表示任何类型, type/ 表示该类型下的所有子类型
Accept-Encoding
作用: 浏览器申明自己接受的编码方法,通常指定压缩方法,是否支持压缩,支持什么压缩方法(gzip,deflate) 注意这不是指字符编码
Accept-Language
作用: 浏览器申明自己接收的语言 语言和字符集不同
Accept-Charset
作用: 浏览器声明自己接受的字符集编码
User-Agent
作用: 表示请求者的一些信息,比如 浏览器类型和版本 操作系统 使用语言等
Cookie/Login头域
Cookie
作用: HTTP请求发送时,会把保存在该请求域名下的所有cookie值发送给Web服务器
Entity头域
Content-Type
作用: 表示后面的消息体属于什么MIME类型.通常需要显示地指定为text/html. 而对于基于json的REST交互,则需要配置为application/json.
Content-Length
作用: 表示消息体的长度.可以用来判断消息体是否传递完整
Miscellaneous头域
Referer
作用: 提供Request的上下文信息的服务器,告诉服务器我是从哪个链接过来的.
Transport头域
Connection
作用: 控制TCP连接是否断开
例子:
- Connection: keep-alive 当一个HTTP请求结束后,TCP连接不会断开,如果客户端再次访问服务器上的网页,会继续使用这条TCP连接
- Connection: close 代表一个HTTP请求完成后,客户端与服务器之间的TCP连接会关闭,当客户端再次发送HTTP请求时,重新创建TCP连接
Host
作用: 请求报头域主要用于指定被请求资源的Internet主机和端口
响应头
Cache头域
Date
作用: 生成消息的具体时间和日期
Expires
作用: 浏览器会在指定过期时间内使用本地缓存
Vary
作用: 对于未来的请求头,应该用一个缓存回复还是向源服务器请求一个新的回复
Cookie/Login头域
P3P
作用: 用于跨域设置Cookie, 这样可以解决iframe跨域访问cookie的问题
Set-Cookie
作用: 用于把cookie发送到客户端.
Entity头域
ETag
作用: 和If-None-Match配合使用
Last-Modified
作用: 用于指示资源的最后修改日期和时间
Content-Type
作用: Web服务器告诉客户端自己的响应的内容的类型和字符集
Content-Length
作用: 指明实体正文的长度,以字节方式存储的十进制数字来表示.
Content-Encoding
作用: Web服务器表明自己使用什么压缩方法(gzip, deflate)
Content-Language
作用: Web服务器告诉浏览器自己响应的对象的语言
Miscellaneous头域
Server
作用: 指明HTTP服务器的软件信息
Transport头域
Connection
作用: 同上请求头中Connection
Location头域
Location
作用: 用于重定向一个新的位置,包含新的
URI和URL的区别
URI
URI 是uniform resource identifier, 统一资源标识符,用来唯一的标识一个资源
Web上可用的每种资源如HTML文档,图像,视频片段,程序等都是一个URI来定位
URI一般由三部分组成:
- 访问资源的命名机制
- 存放资源的主机名
- 资源自身的名称,由路径标识,着重强调于资源.
URL
URL 是uniform resource locator, 统一资源定位器, 它是一种具体的URI, 即URL可以用来标识一个资源, 而且还可以指明了如果locate这个资源
采用URL可以用一种统一的格式来描述各种信息资源,包括文件,服务器的地址和目录等.URL一般由三部分组成:
- 协议(或称为服务方式)
- 存在该资源的主机IP地址
- 主机资源的具体地址.如果目录和文件名等.
URN
URN 是uniform resource name, 统一资源命名,是通过名字来标识资源
HTTP工作原理
HTTP协议定义Web客户端如果从Web服务器请求Web页面,以及服务器如何把Web页面传送给客户端.HTTP协议采用了请求/响应模型.客户端向服务器发送一个请求报文,请求报文包含请求的方法,URL,协议版本,请求头部和请求数据.服务器以一个状态行作为响应,响应的内容包括协议的版本,成功或者错误代码,服务器信息,相应头部和响应数据
以下是HTTP请求/响应的步骤:
- 客户端连接到Web服务器
一个HTTP客户端,通常是浏览器,与Web服务器的HTTP端口(默认为80)建立一个TCP套接字连接. - 发送HTTP请求
通过TCP套接字,客户端向Web服务器发送一个文本的请求报文,一个请求报文由请求行,请求头部,空行和请求数据4部分组成 - 服务器接收请求并返回HTTP响应
Web服务器解析请求,定位请求资源.服务器将资源复本写到TCP套接字,由客户端读取.一个响应由状态行,响应头部,空行和响应数据4部分组成 - 释放TCP连接
若connection模式为Close,则服务器主动关闭TCP连接,客户端被动关闭连接,释放TCP连接;若connection模式为keeplive,则该连接保持一段时间,在该时间内可以继续接受请求. - 客户端浏览器解析HTML内容
客户端浏览器首先解析状态行,查看是否请求成功,然后解析每一个响应头,响应头告知以下为若干字节的HTML文档和文档的字符集.客户端浏览器读取响应数据HTML,根据HTML的语法对其进行格式化,并在浏览器窗口中进行显示.
例如:在浏览器中输入URL,按下回车后会经历以下流程:
- 浏览器向DNS服务器请求解析该URL中的域名所对应的IP地址
- 解析出IP地址后,根据该IP地址和默认端口80,和服务器建立TCP连接
- 浏览器发出读取文件的HTTP请求,该请求报文作为TCP三次握手的第三个报文的数据发送给服务器
- 服务器对浏览器请求做出响应,并把对应的HTML文本发送给浏览器
- 释放TCP连接
- 浏览器将该HTML文本显示内容