• 微信号
  • 微信号
您当前的位置:首页 > 学海无涯 > 茑语花香>HTTP(hypertext transport protocol)协议

HTTP(hypertext transport protocol)协议

孤峰 孤峰家 2023-08-08 45人阅读

1989年,蒂姆·伯纳斯 - 李(Tim Berners-Lee)在论文中提出可以在互联网上构建超链接文档,并提出了三点。

URI:统一资源标识符。互联网的唯一ID

HTML:超文本文档

HTTP:传输超文本的文本传输协议

1、HTTP应用在哪儿

学习一门知识,采用五分钟时间看看这个知识是干啥的可能会更加有目的性。HTTP可谓无处不在,这里例举出几个。

HTTP应用场景

2、HTTP是什么

HTTP(hypertext transport protocol)翻译过来为"超文本传输协议",文本可以理解为简单的字符文字组合,也可以理解为更为复杂的音频或者图像等。那么将这个词语拆分为三个部分。

超文本传输协议

“超文本""文本"相比多了一个字"超”,这样看来比文本丰富,因为它可以将多种文本/图像等进行混合,更重要的是可以从一个文本跳转到另一个文本(文本连接)。

“传输”,传输的过程中需要沟通,沟通即可能一对一沟通也可能一对多沟通(进行内容协商),无论怎么样,参加沟通的人数>1,想尽一切一切办法更快更好的完成相应的任务。

“协议”,无规矩不成方圆,做机密项目之前需要签署保密协议,找工作要签"三方协议",三方协议是学校,公司,和个人组成的协议,都是为了让大家受一定的约束,违反了即有相应的惩罚。

三方协议

3、不同版本的HTTP

HTTP/0.9

GET /Mysite.html响应中只包含了文档本身。响应内容无响应头,无错误码,无状态码,可以说是"裸奔"。
<HTML> 

Hello world

</HTML>

HTTP/1.0

此时 HTTP/0.9 请求过程如下

应用层的HTTP建立在传输层的TCP之上并运用TCP可靠性等特性,先三次握手建立连接

客户端请求建立连接(此时只有GET)

服务端响应请求,数据以 ASCII 字符流返回给客戶端

传输完成,断开连接。

HTTP 0.9

HTTP1.0

随着时代的进步,仅仅文本的传输无法满足需求,更多情况需要采用图文的方式才能生动的表达出自己的观点。随着1995年开发出Apache,同时其他的多媒体等技术发展迅速,从而进一步的促使HTTP新功能的出现。HTTP1.0在1996年诞生,增加了一下几个方面:

之前只有Get方法,现在增加Post(加参数),Head方法

加入协议版本号,同时添加文件处理类型

加入HTTP Header,让HTTP处理请求更加灵活

增加响应状态码,标记出错的原因

提供国际化(不同语言)支持

典型的请求过程

GET /i**ge.html HTTP/1.0 

User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64)200 OK

Date: Tue, 17 Nov 2020 09:15:31 GMT

Content-Type: text/html

<HTML>

一个包含图片的页面<IMG SRC="/i**ge.gif">

</HTML>

HTTP1.0通信过程

HTTP /1.1

1995年是不平凡的一年,网景公司和微软开启浏览器大战,谁都想当老大。1999年HTTP/1.1发布并成为标准,写入RFC,以为以后不管是**还是APP等,只要你要使用HTTP,就得遵守这个标准。

继续增加了PUT等方法

允许持久连接

随着文件越来越大,图片等信息越来越复杂,如果每一次上传下载文件都需要建立连接断开连接的过程将增加大量的开销。为此,提出了持久连接,也就是一次TCP连接可以具有多个HTTP请求。当然持久连接是可选择的,如果考虑关闭,只需要使用Connecttion:close关闭即可。长连接如下图所示:

强制要求Host头

我们知道,在电商系统中,经常会因为促销活动导致流量飙升,为了缓解流量,其中有种方法即加缓存或者加服务器。如果是单台服务器负载过大,数据库可能分库分表。数据结构算法中分而治之方法亦是如此。那么HTTP中,同样的道理,如果文件太大,就大文件切分为小文件块发送。

HTTP /2

HTTP/1.1的出现,几年间出来大量牛掰的互联网公司,发展实在是太快,但是HTTP1.1中这几点成为诟病。

原因1 TCP自带慢启动

顾名思义,"慢启动"从0到1循循渐进。轿车启动不会按下按钮就直接起飞,而是缓慢调节到适合的速度。这不是挺好的?为什么会带来性能问题呢。我们知道一个页面有静态数据,动态页面,很多小文件在加载的过程中就会直接发起请求,这样导致太多的请求都会经历慢启动过程,花费时间太多。

原因2 多条TCP连接带宽竞争

带宽固定,多条TCP连接同时发起竞争带宽资源,由于各个TCP连接之间没有通信机制,也无法得知哪些资源优先级更高,从而导致想快速下载的资源反而延迟下载。

原因3 头部阻塞

阻塞,在网络编程中,我们采用异步,多路复用(epoll)方式尽量让cpu少等待多干事。在HTTP1.1中,虽然大家共用了一条TCP通道,但是第一个请求没有结束,第二请求就可能阻塞等待,也就是说不能同时发送接收数据。那么一个网页很多数据文件,如果能够同时发出请求,让部分数据文件能够得到响应并预处理,这样就大大的利用了带宽和cpu的资源。基于这些因素,在HTTP2中出现了新的方案。

如何解决头部阻塞呢?

HTTP是一问一答的模式,大家都在这个队列排队导致堵塞,那就多个队列并发进行,也就是"对同一个域名发起多个长连接"。举个例子,在火车站排队买票的时候,如果只有一个窗口可用,大家只能苦等,多开几个窗口就可缓解这个问题。

这个时候用户数 * 并发数(上限6-8)已经不错得效果,但是互联网速度太快,火车站就这么大,窗口也就这么多,怎么办,建新的火车站进行分流(大部分城市都有什么东站 西站)。在这里叫做"域名分片",使用多个域名,这些域名指向同一服务器。

HTTP/3

HTTP/2看似很完美了吧,但是Google轮子哥可不服,其他人在研究HTTP/2的时候,它们就在琢磨QUIC。那QUIC有啥牛掰的地方呢?

QUIC是Google开发的一个基于UDP且能像TCP一样具有可靠性特点的协议。具备像HTTP/2一样的应用数据二进制分帧传输。其主要解决的问题有两个。

进一步解决线头阻塞问题。通过独立不同流,让各个流之间实现相互独立传输,互不干扰。

切换网络时的连接保持。wifi和3G/4G经常需要来回切换。基于TCP的协议,会因为网络的切换导致IP地址的改变。而基于UDP的QUIC协议,及时切换也可以恢复之前与服务器的连接。(这里推荐大家可以去看看MPTCP)。 4、HTTP报文详解

客户端与服务端进行交互的信息为报文。客户端为请求报文,服务端为响应报文。我们先用wireshark抓一个博客看看。

报文层次结构

GET /article/12 HTTP/1.1 

Host: **.xxx.cn

Connection: keep-alive

Cache-Control: **x-age=0

Upgrade-Insecure-Requests: 1

User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.106 Safari/537.36

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,i**ge/webp,i**ge/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9

Accept-Encoding: gzip, deflate

Accept-Language: zh-CN,zh;q=0.9

Cookie: SESSION=so9nlsvenminor5abs65sh9dsa

HTTP/1.1 200 OK 

Server: nginx

Date: Sun, 17 May 2020 17:04:29 GMT

Content-Type: text/html; charset=UTF-8

Transfer-Encoding: chunked

Connection: keep-alive

Vary: Accept-Encoding

X-Powered-By: blade-2.0.6-BETA

Content-Encoding: gzip

请求报文

请求报文

请求报文通常由三部分组成:

起始行:描述请求或者响应的基本信息

头部字段**:key-value形式说明报文

消息正文:实际传输诸如图片等信息。具体如下图所示

4.1 请求方法

一共有八种方法选择,如下图所示。采用不同的方法获取不同的资源。

说一下非常常见的几种请求方法

Get:从服务器中取资源。可以请求图片,视频等

HEAD:和Get类似,但是从服务器请求的资源不会返回请求的实体数据,只会返回响应头

POST/PUT:对应于GET,向服务器发送数据

4.2 URI

统一资源标识符(Uniform Resource Identifier),严格来说不等于网址,它包含URL和URN,可是URL太出名了以致于URL=“网址”。无论开发,测试运维配置都离不开 URI,所以好好掌握。

网络层的IP主要目的是解决路由寻址。现在的IP地址按照"."分割,总共2322^{32}232次方大约 42 亿。对于计算机来说比较方便,但是对于人类来说还是不容易记忆,此时出现 DNS了,他把IP地址映射为我们平时常见的 redis.org,按照 .分割域名,从左到右级别越高,最右边为顶级域名。如下图所示

域名体系

好了,现在TCP提供可靠(数据不丢失)且字节流(数据完整性),而且也有方便我们记忆的域名,但是互联网资源千万种,也不知道访问什么(图片,文字,视频一大堆),这个时候 URI(统一资源标识符)出现了,那长啥样?

URI格式

协议名:HTTP协议,另外还有ftp等协议。告知访问资源时使用什么协议。

紧接着是分隔符:://

主机名:标记互联网主机,可以是IP也可以是域名,如果不写端口则使用默认端口,例如 HTTP为80,HTTPS为 443。

登录认证信息:登录主机时的用户名密码(不建议,直接告诉了别人你的隐私信息)。

主机名:此处可以是域名也可以是IP,如果不写端口号则是默认端口。比如HTTP默认端口为80,HTTPS默认端口为443。

资源所在位置:资源在主机上的位置,使用 / 分隔多级目录,在这里是/en/download.html。注意,必须 / 开头。

参数:用 ? 开始,表示额外的请求要求。通常使用key=value 的方式存在,如果多个 key=value 则使用 & 相连。

看几个例子

http://nginx.org/en/download.html

file:///E:/Demo/index/

这里注意是三个 ///,因为前面 :// 作为分隔符,资源路径按照 / 开头。

既然规则这么多,对于接收方而言需要完成的解析也需要遵守规则,全球用户很多使用 HTTP,每个国家地区所使用语言不同,HTTP 为了能对其进行统一处理,引入了 URI 编码,方法比较简单,将非 ASCII 或者特殊字符全部转换为十六进制字节值,同时在前面加入%。比如空格被转换为%20,中国就编码为%E4%B8%AD%E5%9B%BD%0A。

4.3 状态码

响应报文

状态行----服务器响应的状态

<1> 版本号:使用的HTTP什么版本。

<2> 状态码:不同数字代表不同的结果,就如我们在编码时,通过返回不同的值代表不同的语义。

状态码一共分为5类。

1××:处于中间状态,还需后续操作。

2××:成功收到报文并正确处理。

200 OK

最常见的成功状态码,表示一切正常,客户端获得期许的处理结果。如果不是 Head 请求,那么在响应头中通常会有 body 数据。

204 No Content

这个的含义和"200"很相似,不同之处在于它的响应头中没有body数据

206 Partial Content

是 HTTP 分块下载或断点续传的基础,在客户端发送“范围请求”、要求获取资源的部分数据时出现,它与 200 一样,也是服务器成功处理了请求,但 body 里的数据不是资源的全部,而是其中的一部分。状态码 206 通常还会伴随着头字段“Content-Range”,表示响应报文里 body 数据的具体范围,供客户端确认,例如“Content-Range: bytes 0-99/5000”,意思是此次获取的是总计 5000 个字节的前 100 个字节。

3××:重定向到其他资源位置

301 Moved Per**nently:“长久重定向”,意思是本地请求的资源不存在,使用新的URI再次访问。

302 Found:“Moved Temporarily”,“临时重定向”,临时则所请求的资源暂时还在,但是目前需要用另一个URI访问。

301 和 302 通过在字段Location中表明需要跳转的URI。两者较大的不同在于一个是临时改变,一个是长久改变。举个例子,有时候需要将网站全部升级为HTTPS,这种长久性改变就需要配置长久的"301"。有时候晚上更新系统,系统暂时不可用,可以配置"302"临时访问,此时不会做缓存优化,第二天还会访问原来的地址。

304 Not Modified:运用于缓存控制。它用于 If-Modified-Since 等条件请求,表示资源未修改,可以理解成“重定向已到缓存的文件”(即“缓存重定向”)。

4××:请求报文有误,服务器无法处理

400 Bad Request:通用错误码,表示请求报文有错误,但是这个错误过于笼统。不知道是客户端还是哪里的错误,所以在实际应用中,通常会返回含有明确含义的状态码。

403 Forbidden:注意了,这一个是表示服务器禁止访问资源。原因比如涉及到敏感词汇、法律禁止等。当然,如果能让客户端有一个清晰的认识,可以考虑说明拒绝的原因并返回即可。

404 Not Found:这可能是我们都知道且都不想看到的状态码之一,它的本意是想要的资源在本地未找到从而无法提供给服务端,但是现在,只要服务器"耍脾气"就会给你返回 404,而我们也无从得知后面到底是真的未找到,还是有什么别的原因,

405 Method Not Allowed:获取资源的方法好几种,我们可以对某些方法进行限制。例如不允许 POST 只能 GET。

406 Not Acceptable:客户端资源无法满足客户端请求的条件,例如请求需要中文但只有英文;

408 Request Timeout:请求超时,服务器等待了过长的时间;

409 Conflict:多个请求发生了冲突,可以理解为多线程并发时的竞态;

413 Request Entity Too Large:请求报文里的 body 太大;

414 Request-URI Too Long:请求行里的 URI 太大;

429 Too Many Requests:客户端发送了太多的请求,

通常是由于服务器的限连策略;

431 Request Header Fields Too Large:请求头某个字段或总体太大;

5××:服务器错误,服务器对请求出的时候发生内部错误。

500 Internal Server Error

和400 类似,属于一个通用的错误码,但是服务器到底是什么错误我们不得而知。其实这是好事,尽量少的将服务器资源暴露外网,尽量保证服务器的安全。

502 Bad Gateway

通常是服务器作为**或者代理时返回的错误码,表示服务器自身工作正常,访问后端服务器时发生了错误,但具体的错误原因也是不知道的。

503 Service Unavailable

表示服务器当前很忙,暂时无法响应服务,我们上网时有时候遇到的“网络服务正忙,请稍后重试”的提示信息就是状态码 503。

503 是一个“临时”的状态,

暂时比较忙,稍后提供服务。在响应报文中的“Retry-After”字段,指示客户端可以在多久以后再次尝试发送请求。 4.4 请求体

上面大部分都是涉及到header部分,还有非常重要的body,everybody。

头字段注意事项

<1> 字段名不区分大小写,例如“Host”也可以写成“host”,但首字母大写的可读性更好;

<2> 字段名里不允许出现空格,可以使用连字符“-”,但不能使用下划线"_"。例如,“test-name”是合法的字段名,而“test name”“test_name”是不正确的字段名;

<3> 字段名后面必须紧接着“:”,不能有空格,而":"后的字段值前可以有多个空格;

<4> 字段的顺序是没有意义的,可以任意排列不影响语义;

<5> 字段原则上不能重复,除非这个字段本身的语义允许,例如 Set-Cookie。

HTTP的body常常被分为这几种的类别

<1> text:超文本text/html,纯文本text/plain

<2> audio/video:音视频数据

<3> application: 可能是文本,也可能是二进制,交给上层应用处理

<4> i**ge: 图像文件。i**ge/png等

但是带宽一定,数据大了通常考虑使用压缩算法进行压缩,在HTTP中使用Encoding type表示,常用的压缩方式有下面几种

转载:感谢您阅览,转载请注明文章出处“来源从小爱孤峰知识网:一个分享知识和生活随笔记录的知识小站”。

链接:HTTP(hypertext transport protocol)协议http://www.gufeng7.com/niaolang/1810.html

联系:如果侵犯了你的权益请来信告知我们删除。邮箱:119882116@qq.com

标签: