Http协议详解

HTTP简介

HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。
HTTP是一个基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)。
HTTP是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统。它于1990年提出,RFC 1945定义了HTTP/1.0版本。其中最著名的就是RFC 2616。RFC 2616定义了今天普遍使用的一个版本——HTTP 1.1。
HTTP是一个应用层协议,由请求和响应构成,是一个标准的客户端服务器模型。HTTP是一个无状态的协议。通常承载于TCP协议之上,有时也承载于TLS或SSL协议层之上,这个时候就是HTTPS。默认HTTP的端口号为80,HTTPS的端口号为443。
20200409120129

无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。

无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。

URI和URL的区别

URI,是uniform resource identifier,统一资源标识符,用来唯一的标识一个资源。Web上可用的每种资源如HTML文档、图像、视频片段、程序等都是一个来URI来定位的。

URL是uniform resource locator,统一资源定位器,它是一种具体的URI,即URL可以用来标识一个资源,而且还指明了如何locate这个资源。URL是Internet上用来描述信息资源的字符串,主要用在各种WWW客户程序和服务器程序上,特别是著名的Mosaic。

URN,uniform resource name,统一资源命名,是通过名字来标识资源,比如mailto:java-net@java.sun.com

URI是以一种抽象的,高层次概念定义统一资源标识,而URL和URN则是具体的资源标识的方式。URL和URN都是一种URI。笼统地说,每个 URL 都是 URI,但不一定每个 URI 都是 URL。这是因为 URI 还包括一个子类,即统一资源名称 (URN),它命名资源但不指定如何定位资源。上面的 mailto、news 和 isbn URI 都是 URN 的示例。

HTTP请求Request

请求报文4部分组成:请求行(request line)、请求头部(header)、空行和请求数据四个部分组成。

20200410094356

请求行:Method Request-URI HTTP-Version 结尾符(结尾符一般用\r\n)

请求头:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Date:表示消息产生的日期和时间
Cache-Control:用于指定缓存指令,缓存指令是单向的(响应中出现的缓存指令在请求中未必会出现),且是独立的(一个消息的缓存指令不会影响另一个消息处理的缓存机制)

Host:初始URL中的主机和端口
User-Agent:发送请求的浏览器类型、操作系统等信息
Accept:客户端可识别的内容类型列表,用于指定客户端接收那些类型的信息
Accept-Encoding:客户端可识别的数据编码
Accept-Language:表示浏览器所支持的语言类型
Authorization:授权信息,通常出现在对服务器发送的WWW-Authenticate头的应答中
Connection:允许客户端和服务器指定与请求/响应连接有关的选项,例如这是为Keep-Alive则表示保持连接。
Transfer-Encoding:告知接收端为了保证报文的可靠传输,对报文采用了什么编码方式。
Content-Length:表示请求消息正文的长度
Cookie:这是最重要的请求头信息之一

From:请求发送者的email地址,由一些特殊的Web客户程序使用,浏览器不会用到它

If-Modified-Since:只有当所请求的内容在指定的日期之后又经过修改才返回它,否则返回304“Not Modified”应答
Pragma:指定“no-cache”值表示服务器必须返回一个刷新后的文档,即使它是代理服务器而且已经有了页面的本地拷贝

Referer:包含一个URL,用户从该URL代表的页面出发访问当前请求的页面
User-Agent:浏览器类型,如果Servlet返回的内容与浏览器类型有关则该值非常有用

Content-Type:发送给接收者的实体正文的媒体类型
Content-Lenght:实体正文的长度
Content-Language:描述资源所用的自然语言,没有设置则该选项则认为实体内容将提供给所有的语言阅读
Content-Encoding:实体报头被用作媒体类型的修饰符,它的值指示了已经被应用到实体正文的附加内容的编码,因而要获得Content-Type报头域中所引用的媒体类型,必须采用相应的解码机制。
Last-Modified:实体报头用于指示资源的最后修改日期和时间
Expires:实体报头给出响应过期的日期和时间

HTTP请求Response

HTTP响应也由四个部分组成,分别是:状态行、消息报头、空行和响应正文。

20200410094437

状态行:HTTP协议版本号, 状态码, 状态消息 三部分组成。((HTTP/1.1)表明HTTP版本为1.1版本,状态码为200,状态消息为(ok))

响应报头

1
2
3
4
5
6
7
8
9
Allow:服务器支持哪些请求方法(如GET、POST等)
Content-Encoding:文档的编码(Encode)方法
Location:用于重定向接受者到一个新的位置,常用在更换域名的时候
Server:包含可服务器用来处理请求的系统信息,与User-Agent请求报头是相对应的
Date:表示消息产生的日期和时间
Content-Type:指定了MIME类型的HTML(text/html),编码类型是UTF-8
Content-Length:表示内容长度
Expires:指明应该在什么时候认为文档已经过期,从而不再缓存它
Refresh:表示浏览器应该在多少时间之后刷新文档,以秒计

状态码

请求成功

1
2
3
4
200 OK : 请求执行成功并返回相应数据,如 GET 成功
201 Created : 对象创建成功并返回相应资源数据,如 POST 成功;创建完成后响应头中应该携带头标 Location ,指向新建资源的地址
202 Accepted : 接受请求,但无法立即完成创建行为,比如其中涉及到一个需要花费若干小时才能完成的任务。返回的实体中应该包含当前状态的信息,以及指向处理状态监视器或状态预测的指针,以便客户端能够获取最新状态。
204 No Content : 请求执行成功,不返回相应资源数据,如 PATCH , DELETE 成功

重定向

重定向的新地址都需要在响应头 Location 中返回

1
2
3
4
301 Moved Permanently : 被请求的资源已永久移动到新位置
302 Found : 请求的资源现在临时从不同的 URI 响应请求
303 See Other : 对应当前请求的响应可以在另一个 URI 上被找到,客户端应该使用 GET 方法进行请求
307 Temporary Redirect : 对应当前请求的响应可以在另一个 URI 上被找到,客户端应该保持原有的请求方法进行请求

条件请求

1
2
3
304 Not Modified : 资源自从上次请求后没有再次发生变化,主要使用场景在于实现数据缓存
409 Conflict : 请求操作和资源的当前状态存在冲突。主要使用场景在于实现并发控制
412 Precondition Failed : 服务器在验证在请求的头字段中给出先决条件时,没能满足其中的一个或多个。主要使用场景在于实现并发控制

客户端错误

1
2
3
4
5
6
7
8
9
10
11
400 Bad Request : 请求体包含语法错误
401 Unauthorized : 需要验证用户身份,如果服务器就算是身份验证后也不允许客户访问资源,应该响应 403 Forbidden
403 Forbidden : 服务器拒绝执行
404 Not Found : 找不到目标资源
405 Method Not Allowed : 不允许执行目标方法,响应中应该带有 Allow 头,内容为对该资源有效的 HTTP 方法
406 Not Acceptable : 服务器不支持客户端请求的内容格式,但响应里会包含服务端能够给出的格式的数据,并在 Content-Type 中声明格式名称
410 Gone : 被请求的资源已被删除,只有在确定了这种情况是永久性的时候才可以使用,否则建议使用 404 Not Found
413 Payload Too Large : POST 或者 PUT 请求的消息实体过大
415 Unsupported Media Type : 服务器不支持请求中提交的数据的格式
422 Unprocessable Entity : 请求格式正确,但是由于含有语义错误,无法响应
428 Precondition Required : 要求先决条件,如果想要请求能成功必须满足一些预设的条件

服务端错误

1
2
3
4
500 Internal Server Error : 服务器遇到了一个未曾预料的状况,导致了它无法完成对请求的处理。
501 Not Implemented : 服务器不支持当前请求所需要的某个功能。
502 Bad Gateway : 作为网关或者代理工作的服务器尝试执行请求时,从上游服务器接收到无效的响应。
503 Service Unavailable : 由于临时的服务器维护或者过载,服务器当前无法处理请求。这个状况是临时的,并且将在一段时间以后恢复。如果能够预计延迟时间,那么响应中可以包含一个Retry-After 头用以标明这个延迟时间(内容可以为数字,单位为秒;或者是一个 HTTP 协议指定的时间格式)。如果没有给出这个 Retry-After 信息,那么客户端应当以处理 500 响应的方式处理它。

Cookie和Session

Cookie和Session都为了用来保存状态信息,都是保存客户端状态的机制,它们都是为了解决HTTP无状态的问题而所做的努力。

Session可以用Cookie来实现,也可以用URL回写的机制来实现。用Cookie来实现的Session可以认为是对Cookie更高级的应用。

两者的比较

Cookie和Session有以下明显的不同点:

  • Cookie将状态保存在客户端,Session将状态保存在服务器端;
  • Cookies是服务器在本地机器上存储的小段文本并随每一个请求发送至同一个服务器。
  • Session是针对每一个用户的,变量的值保存在服务器上,用一个sessionID来区分是哪个用户session变量,这个值是通过用户的浏览器在访问的时候返回给服务器,当客户禁用cookie时,这个值也可能设置为由get来返回给服务器;
  • 就安全性来说:当你访问一个使用session 的站点,同时在自己机子上建立一个cookie,建议在服务器端的SESSION机制更安全些.因为它不会任意读取客户存储的信息。

Session机制

服务器使用一种类似于散列表的结构来保存信息。

当程序需要为某个客户端的请求创建一个session的时候,服务器首先检查这个客户端的请求里是否已包含了一个session标识session id,如果已包含一个session id则说明以前已经为此客户端创建过session,服务器就按照session id把这个 session检索出来使用(如果检索不到,可能会新建一个),如果客户端请求不包含session id,则为此客户端创建一个session并且生成一个与此session相关联的session id,session id的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串,这个 session id将被在本次响应中返回给客户端保存。

Session的实现方式

使用Cookie来实现:服务器给每个Session分配一个唯一的JSESSIONID,并通过Cookie发送给客户端。
URL回显:URL回写是指服务器在发送给浏览器页面的所有链接中都携带JSESSIONID的参数,这样客户端点击任何一个链接都会把JSESSIONID带会服务器。

Cookie的流程

服务器在响应消息中用Set-Cookie头将Cookie的内容回送给客户端,客户端在新的请求中将相同的内容携带在Cookie头中发送给服务器。从而实现会话的保持。

Web缓存

缓存会根据请求保存输出内容的副本,例如html页面,图片,文件,当下一个请求来到的时候:如果是相同的URL,缓存直接使用副本响应访问请求,而不是向源服务器再次发送请求。

与缓存相关的HTTP扩展消息头

1
2
3
4
5
6
7
Expires:指示响应内容过期的时间,格林威治时间GMT
Cache-Control:更细致的控制缓存的内容
Last-Modified:响应中资源最后一次修改的时间
ETag:响应中资源的校验值,在服务器上某个时段是唯一标识的。
Date:服务器的时间
If-Modified-Since:客户端存取的该资源最后一次修改的时间,同Last-Modified。
If-None-Match:客户端存取的该资源的检验值,同ETag。

缓存生效流程

服务器收到请求时,会在200OK中回送该资源的Last-Modified和ETag头,客户端将该资源保存在cache中,并记录这两个属性。当客户端需要发送相同的请求时,会在请求中携带If-Modified-Since和If-None-Match两个头。两个头的值分别是响应中Last-Modified和ETag头的值。服务器通过这两个头判断本地资源未发生变化,客户端不需要重新下载,返回304响应。

HTTP定义了3种缓存机制

Freshness:允许一个回应消息可以在源服务器不被重新检查,并且可以由服务器和客户端来控制。例如,Expires回应头给了一个文档不可用的时间。Cache-Control中的max-age标识指明了缓存的最长时间;

Validation:用来检查以一个缓存的回应是否仍然可用。例如,如果一个回应有一个Last-Modified回应头,缓存能够使用If-Modified-Since来判断是否已改变,以便判断根据情况发送请求;

Invalidation: 在另一个请求通过缓存的时候,常常有一个副作用。例如,如果一个URL关联到一个缓存回应,但是其后跟着POST、PUT和DELETE的请求的话,缓存就会过期。

https

HTTPS(全称:Hypertext Transfer Protocol over Secure Socket Layer),是以安全为目标的HTTP通道,简单讲是HTTP的安全版。即HTTP下加入SSL层,HTTPS的安全基础是SSL。

有两种基本的加解密算法类型:

  • 对称加密:密钥只有一个,加密解密为同一个密码,且加解密速度快,典型的对称加密算法有DES、AES等;
  • 非对称加密:密钥成对出现(且根据公钥无法推知私钥,根据私钥也无法推知公钥),加密解密使用不同密钥(公钥加密需要私钥解密,私钥加密需要公钥解密),相对对称加密速度较慢,典型的非对称加密算法有RSA、DSA等。

    https的通信过程

    20200410094322