Http协议
超文本传输协议(HTTP)是一个用于传输超媒体文档(例如 HTML)的应用层协议,是一个基于请求与响应模式的、无状态的网络协议。它是为 Web 浏览器与 Web 服务器之间的通信而设计的,但也可以用于其他目的。HTTP 遵循经典的客户端-服务端模型(C/S模型),客户端打开一个连接以发出请求,然后等待它收到服务器端响应。HTTP 是无状态协议,这意味着服务器不会在两个请求之间保留任何数据(状态)。该协议虽然通常基于 TCP/IP 层,但可以在任何可靠的传输层上使用;也就是说,不像 UDP,它是一个不会静默丢失消息的协议。
1.主要特点/特征
①支持客户端/服务器模式。
②简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法有POST、GET、HEAD、OPTIONS、DELETE、TRACE、
PUT七种,常用的是GET和POST。每种方法规定了客户与服务器联系的类型不同。由于 HTTP协议简单,使得 HTTP 服务器的程序规模小,因而通信速度很快。
③灵活:HTTP 允许传输任意类型的数据对象。正在传输的类型由 Content-Type 加以标记。
④无连接:无连接的含义是连接双方在完成交互后不维持连接状态,当客户端发送 新的请求后则开启新的连接。
⑤无状态:HTTP 协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
2.Http协议实现的原理机制
①域名解析
②三次握手过程
③发起Http请求
④响应Http请求并得到HTML代码
⑤浏览器解析HTML代码
⑥浏览器对页面进行渲染呈现给用户
3.信息交互过程
当客户端想要和服务端进行信息交互时(服务端是指最终服务器,或者是一个中间代理),过程表现为下面几步:
①打开一个TCP连接:TCP连接被用来发送一条或多条请求,以及接受响应消息。客户端可能打开一条新的连接,或重用一个已经存在的连接,或者也可能开几个新的TCP连接连向服务端。
②发送一个HTTP报文:HTTP报文(在HTTP/2之前)是语义可读的。在HTTP/2中,这些简单的消息被封装在了帧中,这使得报文不能被直接读取,但是原理仍是相同的。
③读取服务端返回的报文信息。
④关闭连接或者为后续请求重用连接。
当HTTP流水线启动时,后续请求都可以不用等待第一个请求的成功响应就被发送。然而HTTP流水线已被证明很难在现有的网络中实现,因为现有网络中有很多老旧的软件与现代版本的软件共存。因此,HTTP流水线已被在有多请求下表现得更稳健的HTTP/2的帧所取代。
4.一个典型的Http会话
在像 HTTP 这样的Client-Server(客户端-服务器)协议中,会话分为三个阶段:
①客户端建立一条 TCP 连接(如果传输层不是 TCP,也可以是其他适合的连接)。
②客户端发送请求并等待应答。
③服务器处理请求并送回应答,回应包括一个状态码和对应的数据。
从 HTTP/1.1 开始,连接在完成第三阶段后不再关闭,客户端可以再次发起新的请求。这意味着第二步和第三步可以连续进行数次。
5.请求报文与响应报文格式
URL:Uniform Resource Locator,统一资源定位符。是互联网上标准资源的地址,可以在全球范围内唯一的确定一个资源。
URI:Uniform Resource Identifier,统一资源标识符,用于标识一个资源的名称。通过这种名称命名的资源可以被互联网定位和访问。
请求报文包含三部分:
a、请求行:包含请求方法、URI、HTTP协议版本号。
b、请求首部字段。存放着各种请求参数及值,其格式为“参数名:参数值”。
c、空白行。用于分离请求报头与请求正文。
d、请求正文(可能没有)。存放请求携带的参数及值。
响应报文包含三部分:
a、状态行:包含HTTP协议版本号、状态码、状态信息
b、响应首部字段。存放着各种响应参数及值,其格式为“参数名:参数值”。
c、空白行。用于分离响应报头与响应正文。
d、响应正文。响应数据所形成的 HTML 文件内容。
6.常用请求头
Accept: text/html,image/* | 支持的数据类型 |
---|---|
Accept-Charset: utf-8 | 支持的数据的编码字符集 |
Accept-Encoding: gzip | 支持的压缩方式 |
Accept-Language: en-us,zh-cn | 支持的语言 |
Host: localhost:8888 | 请求的主机名 |
Referer: http://www.it315.org/index.jsp | 发送请求的界面对应的 url 防盗链 |
User-Agent: Mozilla/4.0 | 浏览器的相关信息 |
Connection: keep-Alive | 请求完成后,到是断开呢还是连接着 |
Date: Tue, 11 Jul 2000 18:23:51 GMT | 发送请求的时间 |
Cookie: tt=123 | 对具体客户端所做的标记 |
7.常用响应头
Location: /day05/index.jsp | 告诉浏览器重新定向到指定的路径 |
---|---|
Server:apache tomcat | 使用的什么 web 服务器 |
Content-Encoding: gzip | 告诉浏览器我传给你的数据用的压缩方式 |
Content-Length: 80 | 响应体的字节数 |
Content-Language: zh-cn | 响应体数据的语言 |
content-type: text/html; charset=GB2312 | 响应体内容的类型 |
Last-Modified: Tue, 11 Jul 2000 18:23:51 GMT | 资源最后被修改的时间 |
Refresh: 1 | 定时刷新 |
Content-Disposition:attachment;filename=aaa.zip | 文件下载 |
Set-Cookie:SS=Q0=5Lb_nQ; path=/search | 将 cookie 数据回送给 ie |
Expires: -1 | 告诉浏览器不要缓存起来 |
Cache-Control: no-cache | 当 HTTP1.1 服务器指定 CacheControl = no-cache 时,浏览器就不会缓存该网页 |
Connection: close/Keep-Alive | 是否保持连接 |
Date: Tue, 11 Jul 2000 18:23:51 GMT | 响应的时间 |
8.请求方法
①GET: 用于请求访问已经被URI(统一资源标识符)识别的资源,可以通过URL传参给服务器。
②POST:用于传输信息给服务器,主要功能与GET方法类似,但一般推荐使用POST方式。
③PUT: 传输文件,报文主体中包含文件内容,保存到对应URI位置。
④HEAD: 获得报文首部,与GET方法类似,只是不返回报文主体,一般用于验证URI是否有效。
⑤DELETE:删除文件,与PUT方法相反,删除对应URI位置的文件。
⑥OPTIONS:查询相应URI支持的HTTP方法。
表单请求 | 默认 GET,可以指定 POST |
---|---|
AJAX 请求 | 默认 GET,可以指定 POST |
地址栏请求 | GET 请求 |
超链接请求 | GET 请求 |
src 资源路径请求 | GET 请求 |
9.Http1.0
HTTP1.0 协议规定,客户端若要向服务端发出请求,必须首先在它们之间创建一个 TCP(Transfer Control Protocal,传输控制协议)连接。而当客户端接收到服务端所发出的响应后,服务端将关闭 TCP 连接。只有等待上一次的请求所对应的响应被客户端接收到后,客户端才可发出第二次请求。HTTP1.0 协议中的连接属于非持久连接,且服务器不跟踪和记录任何一次请求与响应。客户端和服务端每次建立和关闭连接都是一个相对比较费时的过程,会严重影响客户端和服务端的性能。若一个简单的页面发出了四次请求,使用 HTTP1.0 协议,就需要创建与关闭四次连接,严重影响了服务器的响应速度,降低了用户体验。
![Http1.0](https://i-blog.csdnimg.cn/blog_migrate/05be95e8495e50ef191f0de7f1532602.png#pic_center)
10.Http1.1
HTTP 1.1 是一种持久连接,在一个 TCP 连接上可以传送多个 HTTP 请求和响应,减少了建立和关闭连接的消耗和延迟。一个包含有许多 CSS、JS、图片等资源的页面,其所发出的多个请求和响应可以在一个连接中传输。但每个单独的页面文件的请求和响应仍然需要使用各自的连接。
HTTP 1.1 还允许客户端不用等待上一次请求结果返回,就可以发出下一次请求,但服务器端必须按照接收到客户端请求的先后顺序依次回送响应结果,以保证客户端能够区分出每次请求的响应内容,这样也显著地减少了整个下载过程所需要的时间。
为了防止服务器主动将 TCP 连接关闭,在每一个请求中都携带了一个参数 Connection, 用于告诉服务器是否关闭连接。在 HttpWatch 中可以看到的这些请求中,其 Connection 参数值均为 Keep-Alive 保持连接。只有当客户端发送了关闭 TCP 连接请求时,服务器才会将 TCP 连接关闭。
当然,除了改进了 HTTP1.0 协议的性能问题外,HTTP 1.1 还通过增加更多的请求头和响应头来改进和扩充 HTTP 1.0 的功能。
例如,由于 HTTP 1.0 不支持 Host 请求头属性,WEB 浏览器无法使用主机域名来明确表示要访问服务器上的哪个 WEB 站点,这样就无法使用 WEB 服务器在同一个 IP 地址 和端口号上配置多个虚拟 WEB 站点。在 HTTP 1.1 中增加 Host 请求头字段后,WEB 浏览器可以使用主机域名来明确表示要访问服务器上的哪个 WEB 站点,这才实现了在一台 WEB 服务器上可以在同一个 IP 地址和端口号上使用不同的主机名来创建多个虚拟 WEB 站点。
HTTP 1.1 的持续连接,也需要增加新的请求头来帮助实现,例如,Connection 请求头的值为 Keep-Alive 时,客户端通知服务器返回本次请求的响应后后仍然保持连接;Connection 请求头的值为 close 时,客户端通知服务器关闭连接。
![Http1.1](https://i-blog.csdnimg.cn/blog_migrate/d1f6417b3a12daa9e114dfeaf38cc043.png#pic_center)
11.Http2.0
在HTTP/2中,为了优化和性能方面的改进,曾经可人工阅读的消息被分到多个HTTP帧中。
HTTP/2 引入了一个额外的步骤:它将 HTTP/1.x 消息分成帧并嵌入到流 (stream) 中。数据帧和报头帧分离,这将允许报头压缩。将多个流组合,这是一个被称为 多路复用 (multiplexing) 的过程,它允许更有效的底层 TCP 连接。
HTTP 帧现在对 Web 开发人员是透明的。在 HTTP/2 中,这是一个在 HTTP/1.1 和底层传输协议之间附加的步骤。Web 开发人员不需要在其使用的 API 中做任何更改来利用 HTTP 帧;当浏览器和服务器都可用时,HTTP/2 将被打开并使用。
12.Http1.0和1.1的区别
(1) HTTP1.0
HTTP1.0 协议中的连接属于非持久连接,一次 TCP 连接只能进行一次请求与响应。
一次请求与响应对应一个 TCP 连接。
客户端只有在接收到服务端对上一次请求的响应后,客户端才可发出第二次请求。
HTTP1.0 不支持对虚拟主机的访问。因为其没有 HOST 请求头属性,会将用户所发出的域名直接通过 DNS 转换为 IP 后,发送到服务端。也就是说,服务端接收到的直接就是个 IP 而非域名。这样 HTTP1.0 的请求就不支持对虚拟主机的访问了。
HTTP1.0 协议中在客户端接收到服务端的响应后,马上发送关闭 TCP 连接的请求,服务端关闭连接。
(2) HTTP1.1
HTTP 1.1 支持持久连接,在一个 TCP 连接上可以传送多个请求和响应。
一般情况下,一个页面中的请求与响应对应一个 TCP 连接。
HTTP 1.1 还允许客户端不用等待上一次请求结果返回,就可以发出下一次请求。
HTTP1.1 支持对虚拟主机的访问。其在请求头属性中增加了 HOST 属性,用于记录请求所要访问的虚拟域名。当然,请求中所携带的域名,肯定会通过 DNS 将其转换为 IP, 然后查找到相应的主机。但由于请求中还携带有 HOST 属性,即要访问的域名仍然在请求中,这样的话,服务器就可以从请求中解析出请求所要访问的虚拟主机名。
HTTP1.1 协议中在客户端接收到对最后一次请求的响应后,马上发送关闭 TCP 连接请求, 服务端关闭连接。
13.Http1.1和2.0的区别
HTTP/2在HTTP/1.1有几处基本的不同:
HTTP/2是二进制协议而不是文本协议。不再可读,也不可无障碍的手动创建,改善的优化技术现在可被实施。
这是一个复用协议。并行的请求能在同一个链接中处理,移除了HTTP/1.x中顺序和阻塞的约束。
压缩了headers。因为headers在一系列请求中常常是相似的,其移除了重复和传输重复数据的成本。
其允许服务器在客户端缓存中填充数据,通过一个叫服务器推送的机制来提前请求。
14.常见状态码
1xx:指示信息–表示请求已接收,继续处理
2xx:成功–表示请求已被成功接收、理解、接受
3xx:重定向–要完成请求必须进行更进一步的操作
4xx:客户端错误–请求有语法错误或请求无法实现
5xx:服务器端错误–服务器未能实现合法的请求
200:请求被正常处理
204:请求被受理但没有资源可以返回
206:客户端只是请求资源的一部分,服务器只对请求的部分资源执行GET方法,相应报文中通过Content-Range指定范围的资源。
301:永久性重定向
302:临时重定向
303:与302状态码有相似功能,只是它希望客户端在请求一个URI的时候,能通过GET方法重定向到另一个URI上
304:发送附带条件的请求时,条件不满足时返回,与重定向无关
307:临时重定向,与302类似,只是强制要求使用POST方法
400:请求报文语法有误,服务器无法识别
401:请求需要认证
403:请求的对应资源禁止被访问
404:服务器无法找到对应资源
500:服务器内部错误
503:服务器正忙
15.指定默认错误页面
当发生诸如 404、500 错误时,Web 容器给出一个英文提示的页面。若系统给出这样的页面,则说明系统设计的界面不友好。不过,在 web.xml 中允许应用指定默认的错误码所对应的错误页面。只要服务端向客户端浏览器发出指定的状态码,则系统就会自动跳转到指定页面。
修改web.xml,添加以下内容。
<error-page>
<error-code>404</error-code>
<location>/errors.html</location>
</error-page>
16.GET提交
由于 GET 请求会将请求所携带的参数作为请求 URL 中的一部分出现,所以请求参数会显示在地址栏。而这就导致了 GET 提交的三点不足:
参数值只能是字符串,而不能是其它类型
可以携带的数据量小
数据安全性低
但 GET 请求有一个很重要的特征:客户端一旦接收到“服务器向 GET 请求发送的响应” 后,浏览器会自动缓存响应。当客户再次进行相同请求提交时,将直接读取本地浏览器缓存中数据,而不再向服务端真正发送数据,让用户感觉服务端的响应很快,提升用户体验,减轻了服务器压力。
17.POST提交
POST 请求会将请求所携带的数据以请求正文的形式出现,所以与 GET 方式相比,就显示出了三点长处:
数据类型可以是任意类型,还可以是声音、视频、图片等文件
请求可以携带的数据量大
数据安全性高
但发出 POST 请求的客户端浏览器不会对接收到的“服务器向 POST 请求发送的响应” 进行缓存。当用户再次进行相同请求时,仍是真正向服务器发送的请求,从服务器读取的数据。
为什么要设计为“GET 请求的响应结果会被浏览器缓存,POST 请求的响应结果不会被浏览器缓存”呢?主要有两点原因。
一个原因是,以不同的方式提交请求其目的也是不同的。
GET 请求的目的一般是客户端要从服务端下载资源,发送相同的请求就代表要下载相同的资源。既然要下载相同的资源而这些资源已经被下载到了客户端,那么就无需再下载了。所以也就无需再向服务器发送真正的下载请求了。所以就将 GET 提交方式设计为了“GET 请求的响应结果会被浏览器缓存”。
但 POST 请求的目的一般是客户端要向服务器端上传资源。对于向服务器端上传资源后响应结果,浏览器是无需缓存的。
另一个原因是,是否是相同的请求,两种提交方式的比较难易程度是不同的。
GET 提交方式的请求只包含请求行、请求头与空行三部分,请求体为空。所以第二次请求与前一次请求是否相同,浏览器很好做出比较。
但 POST 提交方式所包含的数据量比较大,主要体现在请求正文内容较多上。请求正文可以是图片、音频、视频等文件,而对第二次请求与前一次请求是否相同的比较,仅从这些内容来看就已经很不好比较了。即对于 POST 提交,是否是相同请求的提交是不好做出比较的,或者说是无法进行比较的。所以将 POST 提交方式设计为了“POST 请求的响应结果不会被浏览器缓存”。
18.GET和POST区别
区别一:
get重点在从服务器上获取资源,post重点在向服务器发送数据;
区别二:
get传输数据是通过URL请求,以field(字段)= value的形式,置于URL后,并用"?“连接,多个请求数据间用”&"连接,如http://127.0.0.1/Test/login.action?name=admin&password=admin,这个过程用户是可见的;
post传输数据通过Http的post机制,将字段与对应值封存在请求实体中发送给服务器,这个过程对用户是不可见的;
区别三:
Get传输的数据量小,因为受URL长度限制,但效率较高;
Post可以传输大量数据,所以上传文件时只能用Post方式;
区别四:
get是不安全的,因为URL是可见的,可能会泄露私密信息,如密码等;
post较get安全性较高;
区别五:
get方式只能支持ASCII字符,向服务器传的中文字符可能会乱码。
post支持标准字符集,可以正确传递中文字符。
19.提交方式的选择
根据以上叙述,具有以下几种情况之一的,选择 POST 提交方式。其它均采用 GET 提交方式。
提交时所携带的数据类型不是字符串
提交时所携带的数据量比较大
提交时所携带的数据具有敏感性,安全性要求较高
为什么 POST 提交的安全性就高了?因为能够实现 POST 提交的方式只有两种:通过表单的 POST 提交,与通过 AJAX 的 POST 提交。其它方式均为 GET 提交方式。对于一个提供了POST 登录页面的系统,若用户试图通过地址栏等方式进行登录,则说明其一定是非法登录。也就是说,只要我们设置系统的登录请求提交方式是 POST,那么就会出现以下两种情况:
①若用户以 POST 方式提交登录请求,我们无法判断其是否是非法登录。因为他有可能是通过其它表单的 POST 方式提交的登录请求。
②若用户以 GET 方式提交登录请求,则马上就可以判断其是非法登录。基于以上原因,POST 提交方式的安全性要高于 GET 提交方式。
20.常见MIME类型
文件 | MIME 类型 |
---|---|
超文本标记语言文本 | .html,.html text/html |
普通文本 | .txt text/plain |
RTF 文本 | .rtf application/rtf |
GIF 图形 | .gif image/gif |
JPEG 图形 | .jpeg,.jpg image/jpeg |
au 声音文件 | . au audio/basic |
MIDI 音乐文件 | mid,.midi audio/midi,audio/x-midi |
RealAudio 音乐文件 | .ra, .ram audio/x -pn-realaudio |
MPEG 文件 | .mpg,.mpeg video/mpeg |
AVI 文件 | .avi video/x -msvideo |
GZIP 文件 | .gz application/x -gzip |
TAR 文件 | .tar application/x -tar |
21.HTTP的缺点与HTTPS
①通信使用明文不加密,内容可能被窃听
②不验证通信方身份,可能遭到伪装
③无法验证报文完整性,可能被篡改
HTTPS就是HTTP加上加密处理(一般是SSL安全通信线路)+认证+完整性保护。
22.HTTP优化
利用负载均衡优化和加速HTTP应用
利用HTTP Cache来优化网站
23.什么是Http协议无状态协议?怎么解决Http协议无状态协议?
①无状态协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息
②无状态协议解决办法: 通过1、Cookie 2、通过Session会话保存。
24.长短连接与Http流水线
Http1.1诞生了两个新模型:长连接与Http流水线。
短连接:HTTP 最早期的模型,也是 HTTP/1.0 的默认模型,是短连接。每一个 HTTP 请求都由它自己独立的连接完成;这意味着发起每一个 HTTP 请求之前都会有一次 TCP 握手,而且是连续不断的。TCP 协议握手本身就是耗费时间的,所以 TCP 可以保持更多的热连接来适应负载。短连接破坏了 TCP 具备的能力,新的冷连接降低了其性能。
长连接:短连接有两个比较大的问题:创建新连接耗费的时间尤为明显,另外 TCP 连接的性能只有在该连接被使用一段时间后(热连接)才能得到改善。为了缓解这些问题,长连接 的概念便被设计出来了,甚至在 HTTP/1.1 之前。或者这被称之为一个 keep-alive 连接。
一个长连接会保持一段时间,重复用于发送一系列请求,节省了新建 TCP 连接握手的时间,还可以利用 TCP 的性能增强能力。当然这个连接也不会一直保留着:连接在空闲一段时间后会被关闭(服务器可以使用 Keep-Alive 协议头来指定一个最小的连接保持时间)。
长连接也还是有缺点的;就算是在空闲状态,它还是会消耗服务器资源,而且在重负载时,还有可能遭受 DoS attacks 攻击。这种场景下,可以使用非长连接,即尽快关闭那些空闲的连接,也能对性能有所提升。
Http流水线:流水线是在同一条长连接上发出连续的请求,而不用等待应答返回。这样可以避免连接延迟。理论上讲,性能还会因为两个 HTTP 请求有可能被打包到一个 TCP 消息包中而得到提升。就算 HTTP 请求不断的继续,尺寸会增加,但设置 TCP 的 MSS(Maximum Segment Size) 选项,仍然足够包含一系列简单的请求。
并不是所有类型的 HTTP 请求都能用到流水线:只有 idempotent 方式,比如 GET、HEAD、PUT 和 DELETE 能够被安全的重试:如果有故障发生时,流水线的内容要能被轻易的重试。
今天,所有遵循 HTTP/1.1 的代理和服务器都应该支持流水线,虽然实际情况中还是有很多限制:一个很重要的原因是,目前没有现代浏览器默认启用这个特性。