HTTP
协议(超文本传输协议HyperText Transfer Protocol),它是基于TCP协议的应用层传输协议,简单来讲就是客户端和服务端进行数据传输的一种规则。html
注意:客户端与服务器的角色不是固定的,一端充当客户端,也可能在某次请求中充当服务器。这取决与请求的发起端。HTTP协议属于应用层,创建在传输层协议TCP之上。客户端经过与服务器创建TCP链接,以后发送HTTP请求与接收HTTP响应都是经过访问Socket接口来调用TCP协议实现。web
HTTP
是一种无状态 (stateless) 协议, HTTP
协议自己不会对发送过的请求和相应的通讯状态进行持久化处理。这样作的目的是为了保持HTTP协议的简单性,从而可以快速处理大量的事务, 提升效率。算法
然而,在许多应用场景中,咱们须要保持用户登陆的状态或记录用户购物车中的商品。因为HTTP
是无状态协议,因此必须引入一些技术来记录管理状态,例如Cookie
。编程
HTTP URL
包含了用于查找某个资源的详细信息, 格式以下:后端
http://host[":"port][abs_path]
复制代码
下图是在网上找的一张图,以为能很好的表达HTTP请求的所发送的数据格式。浏览器
由上图能够看到,http请求由请求行,消息报头,请求正文三部分构成。缓存
请求行由请求Method
, URL
字段和HTTP Version
三部分构成, 总的来讲请求行就是定义了本次请求的请求方式, 请求的地址, 以及所遵循的HTTP协议版本例如:安全
GET /example.html HTTP/1.1 (CRLF)
复制代码
HTTP协议的方法有:bash
GET
: 请求获取Request-URI所标识的资源POST
: 在Request-URI所标识的资源后增长新的数据HEAD
: 请求获取由Request-URI所标识的资源的响应消息报头PUT
: 请求服务器存储或修改一个资源,并用Request-URI做为其标识DELETE
: 请求服务器删除Request-URI所标识的资源TRACE
: 请求服务器回送收到的请求信息,主要用于测试或诊断CONNECT
: 保留未来使用OPTIONS
: 请求查询服务器的性能,或者查询与资源相关的选项和需求消息报头由一系列的键值对组成,容许客户端向服务器端发送一些附加信息或者客户端自身的信息,主要包括:服务器
Header | 解释 | 示例 |
---|---|---|
Accept | 指定客户端可以接收的内容类型 | Accept: text/plain, text/html |
Accept-Charset | 浏览器能够接受的字符编码集 | Accept-Charset: iso-8859-5,utf-8 |
Accept-Encoding | 指定浏览器能够支持的web服务器返回内容压缩编码类型 | Accept-Encoding: compress, gzip |
Accept-Language | 浏览器可接受的语言 | Accept-Language: en,zh |
Accept-Ranges | 能够请求网页实体的一个或者多个子范围字段 | Accept-Ranges: bytes |
Authorization | HTTP受权的受权证书类型 | Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== |
Cache-Control | 指定请求和响应遵循的缓存机制 | Cache-Control: no-cache |
Connection | 表示是否须要持久链接(HTTP 1.1默认进行持久链接) | Connection: close |
Cookie | HTTP请求发送时,会把保存在该请求域名下的全部cookie值一块儿发送给web服务器 | Cookie: $Version=1; Skin=new; |
Content-Length | 请求的内容长度 | Content-Length: 348 |
Content-Type | 请求的与实体对应的MIME信息 | Content-Type: application/x-www-form-urlencoded |
Date | 请求发送的日期和时间 | Date: Tue, 15 Nov 2010 08:12:31 GMT |
Expect | 请求的特定的服务器行为 | Expect: 100-continue |
From | 发出请求的用户的Email | From: user@email.com |
Host | 指定请求的服务器的域名和端口号 | Host: www.zcmhi.com |
If-Match | 只有请求内容与实体相匹配才有效 | If-Match: “737060cd8c284d8af7ad3082f209582d” |
If-Modified-Since | 若是请求的部分在指定时间以后被修改则请求成功,未被修改则返回304代码 | If-Modified-Since: Sat, 29 Oct 2010 19:43:31 GMT |
If-None-Match | 若是内容未改变返回304代码,参数为服务器先前发送的Etag,与服务器回应的Etag比较判断是否改变 | If-None-Match: “737060cd8c284d8af7ad3082f209582d” |
If-Range | 若是实体未改变,服务器发送客户端丢失的部分,不然发送整个实体。参数也为Etag | If-Range: “737060cd8c284d8af7ad3082f209582d” |
If-Unmodified-Since | 只在实体在指定时间以后未被修改才请求成功 | If-Unmodified-Since: Sat, 29 Oct 2010 19:43:31 GMT |
Max-Forwards | 限制信息经过代理和网关传送的时间 | Max-Forwards: 10 |
Pragma | 用来包含实现特定的指令 | Pragma: no-cache |
Proxy-Authorization | 链接到代理的受权证书 | Proxy-Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== |
Range | 只请求实体的一部分,指定范围 | Range: bytes=500-999 |
Referer | 先前网页的地址,当前请求网页紧随其后, 即来路 | Referer: www.zcmhi.com/archives/71… |
TE | 客户端愿意接受的传输编码,并通知服务器接受接受尾加头信息 | TE: trailers,deflate;q=0.5 |
Upgrade | 向服务器指定某种传输协议以便服务器进行转换(若是支持) | Upgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11 |
User-Agent | User-Agent的内容包含发出请求的用户信息 | User-Agent: Mozilla/5.0 (Linux; X11) |
Via | 通知中间网关或代理服务器地址,通讯协议 | Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1) |
Warning | 关于消息实体的警告信息 | Warn: 199 Miscellaneous warning |
只有在发送POST
请求时才会有请求正文,GET
方法并无请求正文。
与HTTP请求相似,先上一张图:
HTTP响应也由三部分组成,包括状态行,消息报头,响应正文。
状态行也由三部分组成,包括HTTP协议的版本,状态码,以及对状态码的文本描述。例如:
HTTP/1.1 200 OK (CRLF)
复制代码
状态代码有三位数字组成,第一个数字定义了响应的类别,且有五种可能取值:
1xx
:指示信息 - 表示请求已接收,继续处理2xx
:成功 - 表示请求已被成功接收、理解、接受3xx
:重定向 - 要完成请求必须进行更进一步的操做4xx
:客户端错误 - 请求有语法错误或请求没法实现5xx
:服务器端错误 - 服务器未能实现合法的请求常见状态代码、状态描述、说明:
200
: OK - 客户端请求成功400
: Bad Request - 客户端请求有语法错误,不能被服务器所理解401
: Unauthorized - 请求未经受权,这个状态代码必须和WWW-Authenticate
报头域一块儿使用403
: Forbidden - 服务器收到请求,可是拒绝提供服务404
: Not Found - 请求资源不存在,eg:输入了错误的URL500
: Internal Server Error - 服务器发生不可预期的错误503
: Server Unavailable - 服务器当前不能处理客户端的请求,一段时间后,可能恢复正常StatusCode | StatusCode语义 | 中文描述 |
---|---|---|
100 | Continue | 继续。客户端应继续其请求 |
101 | Switching Protocols | 切换协议。服务器根据客户端的请求切换协议。只能切换到更高级的协议,例如,切换到HTTP的新版本协议 |
200 | OK | 请求成功。通常用于GET与POST请求 |
201 | Created | 已建立。成功请求并建立了新的资源 |
202 | Accepted | 已接受。已经接受请求,但未处理完成 |
203 | Non-Authoritative Information | 非受权信息。请求成功。但返回的meta信息不在原始的服务器,而是一个副本 |
204 | No Content | 无内容。服务器成功处理,但未返回内容。在未更新网页的状况下,可确保浏览器继续显示当前文档 |
205 | Reset Content | 重置内容。服务器处理成功,用户终端(例如:浏览器)应重置文档视图。可经过此返回码清除浏览器的表单域 |
206 | Partial Content | 部份内容。服务器成功处理了部分GET请求 |
300 | Multiple Choices | 多种选择。请求的资源可包括多个位置,相应可返回一个资源特征与地址的列表用于用户终端(例如:浏览器)选择 |
301 | Moved Permanently | 永久移动。请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。从此任何新的请求都应使用新的URI代替 |
302 | Found 临时移动。 | 与301相似。但资源只是临时被移动。客户端应继续使用原有URI |
303 | See Other | 查看其它地址。与301相似。使用GET和POST请求查看 |
304 | Not Modified | 未修改。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。客户端一般会缓存访问过的资源,经过提供一个头信息指出客户端但愿只返回在指定日期以后修改的资源 |
305 | Use Proxy | 使用代理。所请求的资源必须经过代理访问 |
306 | Unused | 已经被废弃的HTTP状态码 |
307 | Temporary Redirect | 临时重定向。与302相似。使用GET请求重定向 |
400 | Bad Request | 客户端请求的语法错误,服务器没法理解 |
401 | Unauthorized | 请求要求用户的身份认证 |
402 | Payment Required | 保留,未来使用 |
403 | Forbidden | 服务器理解请求客户端的请求,可是拒绝执行此请求 |
404 | Not Found | 服务器没法根据客户端的请求找到资源(网页)。经过此代码,网站设计人员可设置"您所请求的资源没法找到"的个性页面 |
405 | Method Not Allowed | 客户端请求中的方法被禁止 |
406 | Not Acceptable | 服务器没法根据客户端请求的内容特性完成请求 |
407 | Proxy Authentication Required | 请求要求代理的身份认证,与401相似,但请求者应当使用代理进行受权 |
408 | Request Time-out | 服务器等待客户端发送的请求时间过长,超时 |
409 | Conflict | 服务器完成客户端的PUT请求是可能返回此代码,服务器处理请求时发生了冲突 |
410 | Gone | 客户端请求的资源已经不存在。410不一样于404,若是资源之前有如今被永久删除了可以使用410代码,网站设计人员可经过301代码指定资源的新位置 |
411 | Length Required | 服务器没法处理客户端发送的不带Content-Length的请求信息 |
412 | Precondition Failed | 客户端请求信息的先决条件错误 |
413 | Request Entity Too Large | 因为请求的实体过大,服务器没法处理,所以拒绝请求。为防止客户端的连续请求,服务器可能会关闭链接。若是只是服务器暂时没法处理,则会包含一个Retry-After的响应信息 |
414 | Request-URI Too Larg | 请求的URI过长(URI一般为网址),服务器没法处理 |
415 | Unsupported Media Type | 服务器没法处理请求附带的媒体格式 |
416 | Requested range not satisfiable | 客户端请求的范围无效 |
417 | Expectation Failed | 服务器没法知足Expect的请求头信息 |
500 | Internal Server Error | 服务器内部错误,没法完成请求 |
501 | Not Implemented | 服务器不支持请求的功能,没法完成请求 |
502 | Bad Gateway | 充当网关或代理的服务器,从远端服务器接收到了一个无效的请求 |
503 | Service Unavailable | 因为超载或系统维护,服务器暂时的没法处理客户端的请求。延时的长度可包含在服务器的Retry-After头信息中 |
504 | Gateway Time-out | 充当网关或代理的服务器,未及时从远端服务器获取请求 |
505 | HTTP Version not supported | 服务器不支持请求的HTTP协议的版本,没法完成处理 |
GET
、HEAD
、POST
。每种方法规定了客户与服务器联系的类型不一样。因为HTTP
协议简单,使得HTTP
服务器的程序规模小,于是通讯速度很快。Content-Type
加以标记。Connection: Keep-Alive
实现长链接HTTP
协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺乏状态意味着若是后续处理须要前面的信息,则它必须重传,这样可能致使每次链接传送的数据量增大。另外一方面,在服务器不须要先前信息时它的应答就较快。在实际的应用中,客户端每每会发出一系列请求,接着服务器端对每一个请求进行响应。对于这些请求|响应,若是每次都通过一个单独的TCP链接发送,称为非持久链接。反之,若是每次都通过相同的TCP链接进行发送,称为持久链接。
非持久链接在每次请求|响应以后都要断开链接,下次再创建新的TCP链接,这样就形成了大量的通讯开销。例如前面提到的往返时间(RTT)
就是在创建TCP链接的过程当中的代价。
非持久链接给服务器带来了沉重的负担,每台服务器可能同时面对数以百计甚至更多的请求。持久链接就是为了解决这些问题,其特色是一直保持TCP链接状态,直到遇到明确的中断要求以后再中断链接。持久链接减小了通讯开销,节省了通讯量。
HTTP
协议中没有加密机制,但能够通 过和 SSL
(Secure Socket Layer, 安全套接层 )或 TLS
(Transport Layer Security, 安全层传输协议)的组合使用,加密 HTTP
的通讯内容。属于通讯加密,即在整个通讯线路中加密。
HTTP + 加密 + 认证 + 完整性保护 = HTTPS(HTTP Secure )
复制代码
HTTPS
采用共享密钥加密(对称)和公开密钥加密(非对称)二者并用的混合加密机制。若密钥可以实现安全交换,那么有可能会考虑仅使用公开密钥加密来通讯。可是公开密钥加密与共享密钥加密相比,其处理速度要慢。
因此应充分利用二者各自的优点, 将多种方法组合起来用于通讯。 在交换密钥阶段使用公开密钥加密方式,以后的创建通讯交换报文阶段 则使用共享密钥加密方式。
HTTPS
握手过程的简单描述以下:
浏览器将本身支持的一套加密规则发送给网站。
服务器得到浏览器公钥
复制代码
网站从中选出一组加密算法与HASH算法,并将本身的身份信息以证书的形式发回给浏览器。证书里面包含了网站地址,加密公钥,以及证书的颁发机构等信息。
浏览器得到服务器公钥
复制代码
得到网站证书以后浏览器要作如下工做:
(a). 验证证书的合法性(颁发证书的机构是否合法,证书中包含的网站地址是否与正在访问的地址一致等),若是证书受信任,则浏览器栏里面会显示一个小锁头,不然会给出证书不受信的提示。
(b). 若是证书受信任,或者是用户接受了不受信的证书,浏览器会生成一串随机数的密码(接下来通讯的密钥),并用证书中提供的公钥加密(共享密钥加密)。
(c) 使用约定好的HASH计算握手消息,并使用生成的随机数对消息进行加密,最后将以前生成的全部信息发送给网站。
浏览器验证 -> 随机密码
服务器的公钥加密 -> 通讯的密钥
通讯的密钥 -> 服务器
复制代码
网站接收浏览器发来的数据以后要作如下的操做:
(a). 使用本身的私钥将信息解密取出密码,使用密码解密浏览器发来的握手消息,并验证HASH是否与浏览器发来的一致。
(b). 使用密码加密一段握手消息,发送给浏览器。
服务器用本身的私钥解出随机密码 -> 用密码解密握手消息(共享密钥通讯)-> 验证HASH与浏览器是否一致(验证浏览器)
复制代码
欢迎关注技术公众号: 零壹技术栈
本账号将持续分享后端技术干货,包括虚拟机基础,多线程编程,高性能框架,异步、缓存和消息中间件,分布式和微服务,架构学习和进阶等学习资料和文章。