文章目录
(四) HTTP协议
0.互联网的诞生
1989年,蒂姆·伯纳斯-李(Tim Berners-Lee)提出了互联网超链接文档系统的三大技术:
①HTML:超文本标记语言,是一棵DOM(document)树,对文档进行展示
②URI/URL:统一资源定位符,对文档进行定位
③HTTP:超文本传输协议,对文档进行传输
这三项技术解决了网络信息在计算机上展示、定位、和传播的问题。
蒂姆把这个系统称为“万维网”(World Wide Web),也就是我们现在所熟知的 Web。
Tim身处欧洲核子研究组织。参考RPC(远程过程调用,即函数调用),设计出了HTTP协议。
1.HTML
超文本标记语言(HTML5,Hypertext Markup Language),是一棵DOM(文档, document)树,对文档进行展示
<html>
<head>
<title> ... </title>
...
</head>
<body>
<form>
...
</form>
</body>
</html>
Web文档:一般用HTML文件描述,布局描述文件是CSS文件,网页脚本文件则是由JavaScript语言
编写的程序。
网页的构成:网页三剑客
(1)HTML:超文本标记语言(Hyper Text Markup Language),是一棵DOM (文档, document)树,有n个结点 [网页的骨架]
(2)CSS:层叠样式表(Cascading Style Sheets),来描述一个网页、HTML文件、XML文件的表现与展示效果,用来对文档进行布局,解决了结点的样式 (字体大小、颜色、位置) [网页的面貌、布局]
(3)JavaScript:脚本语言 (动态语言) [灵魂]
①脚本语言,动态地修改DOM树上结点的信息
②又是动态语言,不需要编译,直接解释执行
2.URI/URL
1.URI:统一资源标识符,Uniform Resource Identifier。URI的两种子类型,URL和URN(Uniform Resource Name)。
URL:统一资源定位符,Uniform Resource Locator。URL不仅标识资源,还提供了访问资源的具体方法。
2.URI/URL的基本结构:
(1)方案(scheme):指定使用的协议,如http、https、ftp等
(2)用户信息(User Information):包括用户名和密码,格式为username:password@,此部分经常被忽略。因为HTTP明文传输,比较危险。
(3)主机(host):资源所在的主机,域名 或 IP地址
(4)端口号(port):指定访问资源的端口号
(5)路径(path):指定资源所在的具体路径,例如 /path/to/resource
①静态资源:直接存储在服务器上的文件,*.html、*.gif、*.jpg、*.mp4
②动态资源:并没有直接存储在服务器上,而需要经过业务逻辑的计算后得到的
(6)查询(querry):查询字符串,用于传递参数。以?
开头,以键值对形式出现 key =
value,多个查询词之间用 &
进行连接。例如:?key1=value1&key2=value2
(7)片段(fragment):指定资源内部的一个部分。前面的连接符是 #
,分段字段和服务端无关,客户端用其来定位网页的阅读起始位置
举例:
例1:
#百度:百度的路径是 /s
https://www.baidu.com/s?wd=百度&ie=UTF-8
#知乎:知乎的路径是 /search
https://www.zhihu.com/search?type=content&q=666
例2:
https://www.baidu.com/s?wd=同济大学
s代表search,wd代表word
例3:
https://username:password@www.example.com:8080/path/to/resource?key1=value1&key2=value2#section1
①方案 (Scheme):https
://
②用户信息 (User Info):username:
password@
③主机 (Host):www.example.com
:
④端口 (Port):8080
⑤路径 (Path):/
path/to/resource
?
⑥查询 (Query):key1=value1&key2=value2
#
⑦片段 (Fragment):section1
3.HTTP协议
(1)概念
1.HTTP,超文本传输协议,HyperText Transfer Protocol
(1)超文本:载荷是超文本或其他数据。【最初传超文本,如xml等网页结构。现在传任何数据,包含图片、视频、二进制信息】
(2)传输:通信的双方基于C-S模型(Client-Server),一个请求(request)对应一个响应(response),一个请求+一个响应称为一个事务,是原子操作。
(3)协议:HTTP是应用层协议,基于传输层的TCP协议。
(2)HTTP协议的特点
HTTP协议的特点:C/S模型、可靠、无状态、文本协议、明文传输的
1.客户端-服务端模型 (C/S模型)
设计思想:函数调用/返回,本地和远程类似 RPC(远程过程调用,Remote Procedure Call)。
客户端是主调方,请求是函数实参,服务器是被调函数,响应是返回值。
2.可靠性:基于TCP协议进行传输
3.无状态协议:每一个HTTP请求都是独立的,不依赖于上下文。(前一个事务执行完成后,没有留下任何额外的数据) (事务:一个请求对应一个响应)
将HTTP设计为无状态协议的好处:
①简化服务器的设计:
每个请求独立,服务器无需维护复杂的会话管理逻辑,从而简化了服务器的实现和维护。
②易于水平扩展,易于实现大并发访问:
易于水平扩展、负载均衡、故障恢复:易于横向扩展,即增加更多服务器来处理请求。易于实现负载均衡。某个服务器出现故障,客户端可以轻松重试请求或将请求发送到另一个服务器。
状态往后移:数据库
状态往前移:客户端,存token。解决了性能问题,但引入了安全问题,只能存不重要的数据。
③MVC模型:
系统架构:三层架构,MVC模型
1>视图展示层:VIEW
2>业务逻辑层:CONTROL
3>数据持久层:MODEL
客户端有需要一些技术支撑:
token技术
cookie技术
session技术
Local Storage技术
4.文本协议:报文头是文本的(字符串)
在有些情况下,可以对HTTP传输的数据进行加密。 TLS/SSL就是一种加密工具,工作在HTTP和TCP之间。我们把基于TLS协议的HTTP称作HTTPS
协议,它提供了更好的安全性。
HTTP协议与TCP协议的区别?
①HTTP是应用层协议,TCP是传输层协议
②HTTP协议无状态,TCP协议是有状态的
③HTTP协议本身是无连接的、无状态的。HTTP协议在发送请求时不需要建立持久连接,每个请求都是独立的。TCP协议是有连接的
④HTTP是文本协议,TCP协议是字节流的、二进制的
(3)两种提升服务器性能的方式
①垂直扩展:买更好的机器。提升单台服务器的CPU、内存、磁盘
②水平扩展:买更多的机器 。买多台服务器,负载均衡
(4)HTTP组件:客户端、服务器、代理
1.HTTP客户端:
(1)浏览器:网址部分输入IP:端口号
(2)curl命令行 (Client URL):curl http://IP:端口号
(3)Postman:图形化界面的接口调试工具,模拟前端请求
sudo apt install curl
curl www.baidu.com //完整报文
curl -I www.baidu.com //报文头
2.服务器:
①Nginx:基于事件驱动,支持高并发
②Apache:底层实现采用子进程模型。基于进程的模型,每一个请求都用一个子进程进行交互。
3.代理:处于客户端与服务器之间的位置
①负载均衡:nginx本身就可以作为反向代理服务器,用来做负载均衡
②日志记录
③信息过滤
④权限控制
(5)如何发起一个HTTP请求?
①通过URL发起
②通过HTML中的一些元素,如 表单
③通过JavaScript语言
4.HTTP报文
(1)HTTP请求报文
①HTTP请求报文的组成部分
①起始行(start line) / 请求行 (Request line):方法、路径、协议版本
②首部字段 (Request Headers)
③空行 (empty line)
④消息体 / 报文体 / 请求体 (Request Body)
HTTP请求报文的格式:
起始行 方法 路径 协议版本 \r\n
首部字段 key1:value1 \r\n
key2:value2 \r\n
\r\n (空行)
[报文体]
举例:
GET /index.html HTTP/1.1
Host: www.example.com
Accept: text/html
Connection: keep-alive
\r:表示回车(Carriage Return),在ASCII编码中对应的值是13,0dx
\n:表示换行(Line Feed),在ASCII编码中对应的值是10,0ax
②HTTP常用的请求方法
(1)GET:查看服务器的一个资源 (Retrieve)。GET请求不携带消息体。
(2)POST:向服务器提交一个新的信息 (Create)
(3)PUT:修改服务器上的一个资源 (Update)
(4)DELETE:删除服务器上的一个资源 (Delete)
(5)HEAD:请求服务器的头信息。类似于GET方法,但服务器仅返回响应头,不返回响应主体。常用于获取资源的元数据。
(6)OPTIONS
(7)PATCH
(8)CONNECT
(9)TRACE
④概念
1.POST请求与GET请求的区别:
(1)POST请求比GET请求 多了消息体:
①GET请求不携带报文体,发给服务器消息比较少时用GET请求,使用查询词
②POST请求携带消息体
(2)用途:GET用于请求数据,POST用于提交数据。
(3)参数位置:GET的参数在url中,POST参数在请求报文(请求主体)中。
2.PUT 与 POST的区别:
POST是增,没有幂等性。
PUT是改,具有幂等性。
3.幂等性
幂等性:重复发请求,结果状态一样。
幂等性的实现:去重。用位图实现。
单线程:不同的请求要有不同的id
多线程:全局
多进程:MySQL、Redis的自增组件
服务器在多地:分布式算法,雪花算法 (SnowFlake),分布式ID生成算法
4.序列化
编码 (序列化):为了跨进程传输数据,让数据结构变为扁平的字节流。
解码(返序列化):让扁平的字节流还原为原本的数据结构
⑤HTTP协议版本
①0.9版本:只有一个GET方法,相当于测试版本。基于TCP。
②1.0版本:包含所有方法,但仅支持短连接。一次请求/响应结束后,TCP会断开连接。效率较低。
③1.1版本:包含所有方法,支持长连接(持久连接,Connect: keep alive)。目前应用最普遍。当Connection: close 表示要断开TCP连接。复用TCP通道,在一个TCP通道中可以发生多次HTTP请求。
④2.0版本:支持二进制信息
⑤3.0版本:支持基于UDP协议传输数据。在网络稳定性越来越好的今天,不担心丢包的情况下,UDP比TCP传输更快,不需要建立连接,少了7次交互。
QUIC协议,QUIC 是 Quick UDP Internet Connections 的缩写,谷歌发明的新传输协议。
⑥消息体 / 报文体(body)类型:Content-Type
(1)GET请求不携带报文体,发给服务器消息比较少时用GET请求,使用查询词
(2)POST请求携带消息体,消息体的三种类型:
①raw类型:text/plain、application/json (json字符串)
[key:content-type,value是 text/plain 或 application/json]
②application/x-www-form-urlencoded:携带的数据量较小
③form-data:传传输文件可以有多个(文件、图片)。传递的数据量较大。
Q:form-data的边界信息(boundary)起什么作用,有什么限制?
A:当传递文件时,为了获取文件的起始位置和结束位置,就加上了边界信息boundary。
boundary起到了分隔不同部分数据的作用。每个部分都包含自己的头部信息和内容,boundary字符串用来明确区分这些部分,以便接收方能够正确解析和处理每个部分的数据。
限制:文件内容不能包含边界
⑦首部字段
Accept字段:表示客户端能够解析的媒体类型
*/* 代表能够接受任意类型
Accept:text/plain
Accept:text/html
Accept:image/png
Accept:application/json
MIME类型
类型/子类型
(2)HTTP响应报文
①HTTP响应报文的组成
①起始行(start line) / 状态行(Status Line)
②首部字段 / 响应头部字段 (Response Headers):Server、Content-Type、Content-Length
③空行 (Empty Line)
④消息体 / 响应主体 (Response Body)
HTTP响应报文的格式:
起始行 协议版本 状态码 原因短语 \r\n
响应头部字段
Server: \r\n
Content-Type: \r\n
Content-Length: \r\n
\r\n (空行)
响应数据
②HTTP状态码
①1xx:连接建立中的情况
②2xx:连接成功,200表示OK;
③3xx:重定向,301 Moved Permanently:请求的资源已永久移动到新位置
④4xx:客户端错误;400 Bad Request:服务器无法理解请求的格式;404 Not Found:请求的资源在服务器上不存在
⑤5xx:服务器错误
③发送HTTP请求
①一个网页,第一次是域名请求,后续是各种网页元素的请求。不止1次http请求
②有磁盘缓存的请求,会比需要从远程服务器下载传输的请求要快得多。
5.HTTPS的原理
HTTP是明文传输的,为了保证数据的安全性,必须对HTTP数据进行加解密的功能/服务。
因此google提出了HTTPS
= HTTP + TLS/SSL
HTTPS的实现原理:
将非对称加密算法和对称加密算法结合起来:
①先用非对称加密算法,传输通信双方的对称加密算法的密钥 [安全性高]
②后续再用对称加密算法进行通信 [效率高]
(1)对称加密
通信双方,只有1把密钥
优势:效率很高
劣势:不够安全,密钥的传输是有风险的
加密运算:异或运算
发送端:a^b = c,接收端:c^b =a
(2)非对称加密
RSA算法,公钥和私钥。通信双方共有4把密钥,双方都有公钥、私钥
过程:接收方产生公钥和私钥,将公钥传输给发送方。发送方根据公钥进行加密并发送。接收方根据私钥解密。[公钥和私钥具有数学相关性,但公钥无法推理出私钥]
举例:从gitee远程拷贝到xshell:Xshell作为接收方,生成公钥和私钥,公钥明文,私钥密文看不见。把公钥粘贴给gitee,这时候再使用git clone命令就可以远程拷贝了。gitee根据公钥加密,xshell根据私钥解密。
优势:安全,安全性很高
劣势:效率低
6.一种比较好的接口设计风格:REST Restful编程风格
1.使用场景:
如果你的服务端的定位是一个工具库,REST接口就是一种很好的风格。把库以网站的形式提供。
2.目标:让程序员用户访问网址,就像调用函数一样。
3.特点:
跨机器、跨语言,不局限于C++库
4.HTTP协议能够进行数据传输的方式很灵活:
①URL中的查询词
②路径
③首部字段
④报文体,不够统一。
5.业界提出了Restful编程风格:
①用路径表示要访问的资源 (区分不同的资源对象)
②用方法表示对于资源的操作
③用请求报文的报文体(消息体)来传递参数,xml、json
④用响应报文的报文体(消息体)来返回结果,当作返回值
看起来很像函数调用与返回。
实际工作中,以公司的约定为准:例如 阿里巴巴的云计算,OSS对象存储服务;微信支付,严格遵循Restful风格。
7.实现HTTP服务器
(1)实现一个简单的HTTP服务器
基于TCP协议,TCP套接字通信流程
(2)作业:http服务器,发送图片给客户端
github代码:https://github.com/WangEdward1027/HTTP
效果展示:
Edge浏览器