目录
什么是HTTP协议
URL与URI
HTTP协议的报文结构
HTTP请求方法
GET请求方法
POST请求方法
HTTP响应状态码
HTTP报文头
HTTP无状态性
HTTP(Hypertext Transfer Protocol):超文本传输协议。
那么说到超文本,我们就会想到HTML (Hyper Text Markup Lanuage)超文本标记语言。而实际上,HTTP协议早期就是专门用来传输HTML文档的。而为了定位HTML文档在网络中的位置,提出了URL(Uniform Resource Locator)统一资源定位符,即URL可以定位到一个资源文件在网络中的位置。
而HTTP,HTML,URL 共同构造了早期的World Wide Web,即万维网。
而随着HTTP的发展,HTTP协议发生了许多变化:
1、HTTP协议不再单纯地用来传输网页内容,而是更加广泛地应用于接口层面数据传输,常见的数据格式有JSON
2、HTTP请求不再只由浏览器发起,现在无论是浏览器还是服务器,或者是手机app都可以发起
3、早期地HTTP请求只能由浏览器刷新网页发起,是同步的,现在有了Ajax,可以发起异步的HTTP请求
无论HTTP协议如何发展,它的基本核心没有变,即HTTP协议是一种请求应答机制的协议,它需要请求一个远程服务器上的某个资源,早期是网页HTML,现在更多是接口JSON数据,但是无论资源如何变化,该资源都要有一个URL标识它在网络中的位置。
URL的组成
URL组成包括:协议,服务器地址,服务器端口号,资源唯一标识,请求参数,锚点,以及它们之间的分隔符
通过URL就可以确定网络中唯一的资源所在位置。
我们通常也将URL称为网址。
那么URI又是什么呢?
URI(Uniform Resource Identifier)统一资源标识符,它是用来定义唯一资源的。即使用一种定义方式让资源唯一。
那么上面的网址是不是可以标识一个唯一资源呢?
答案是可以的。所以URL也是一种特殊的URI。
但是URI还有很多其他表达方式,不一定要写出URL形式。
URI和URL的关系,就像父类和子类一样。子类是一种特殊的父类。URL也是一种特殊的URI。
HTTP协议将报文分为了请求报文和响应报文
HTTP请求报文结构
HTTP请求报文由四部分组成,从上到下依次是:请求行,请求头,空行,请求体
请求行(必传):组成包括请求方法(如POST),请求资源标识(如/api/login),HTTP协议版本(如HTTP/1.1)
请求头(必传):其中都是key:value键值对形式,主要是描述请求相关的信息,如请求的服务器地址,请求体的格式,编码方式,期望服务器响应的报文的格式和编码方式,请求发起方所在的浏览器内核信息,以及操作系统信息,以及一些控制网络连接的设置,
空行(必传):主要用来分隔报文首部和报文主体,请求行和请求头可以看出报文首部,请求体可以看出报文主题。
请求体(可选):请求消息体,即报文的主体内容,可以不传,看业务需求
HTTP响应报文结构
HTTP响应报文也由四部分组成,从上到下依次是:响应行,响应头,空行,响应体
响应行(必传):也叫状态行,用来概括本次响应的状态,组成包括:HTTP协议版本(如HTTP/1.1),状态码(如200),状态码描述(如OK)
响应头(必传):由key:value键值对组成,主要用来描述本次响应的一些信息,如服务器应用程序提供者(如Tomcat,Express,Nginx),是否允许跨域(Acess-Control-Allow-Origin),以及响应体的格式和编码方式(Content-Type),连接设置(Connection),连接失效时间(Keep-Alive)
响应体(可选):即响应消息体,是响应报文的主体内容,其中包含请求方所需的业务数据,但是不是必传的,可以根据业务需求决定。
在HTTP请求报文的请求行中开头就是请求方法,常用的有GET,POST,还有一些不常用,一共有八个
GET |
获取资源,通常不带有报文体内容,它还是默认HTTP请求方法 |
POST | 提交请求,带有报文体的请求 |
OPTIONS | 查询服务器指定资源支持的请求方法 |
HEAD | 和GET类似,但是不返回报文体 |
PUT | 向服务器上传资源,存在安全问题 |
DELETE | 删除服务器上的资源,存在安全问题 |
TRACE | 让服务器将之前的请求通信返回给客户端 |
CONNECT | 用来建立传输通道 |
当前开发过程主要使用GET和POST,其他方式很少在开发中使用。
GET请求方法的作用是 获取 && 检索。
“获取”性质的GET,通常不需要携带请求参数。
“检索”性质的GET,通常需要携带请求参数。
但是GET请求通常不会将请求参数放到请求体中,而是直接拼接在请求URL中。
URL中默认只支持部分ASCII码表中的字符,如常见的英文字母、数字、常用的英文符号。
这是因为URL是西方人设计出来的,他们只考虑了自己的语言环境,使用ASCII码表字符就完全够了。所以URL中如果出现中文字符,那么URL就无法工作了。因为ASCII码表中没有中文字符。
而GET请求参数出现中文字符的场景是很多的,比如常见的百度搜索,我们不可能将想要搜索的中文翻译为英文后搜索。
所以就引入了编码技术,通过将中文字符encode为ASCII码字符,就解决了URL无法识别中文字符的问题了。
我们知道ASCII码表只有128个字符,但是中文字符却有上万个,而中文字符编码后还需要能够适配只识别ASCII码的环境,比如URL。所以新的编码技术顺其自然的通过ASCII码表字符间不同的组合,来一一对应一个中文字符。
比如中文字符编码:GBK
当然除了中文,还有日文,韩文,罗马文,各种国家的文字,他们都需要在网络上传输,那么就需要一种基于ASCII码字符组合兼容万国文字的编码:UTF-8
可以看出GBK表示一个中文字符只需要两个字节
D6D0 为啥是两个字节
一个字节 = 8位 二进制数
0000 0000 ~ 1111 1111
而 4位二进制数,等价于 1位十六进制数
0000 ~ 1111 = 0 ~ F
所以 8位 二进制数,等价于 2位 16进制数
0000 0000 ~ 1111 1111 = 00 ~ FF
所以一个字节 = 2位 十六进制数
而UTF-8表示一个中文字符需要三个字节。
那么GET请求参数使用的是那种编码呢?这和浏览器有关。常用的谷歌浏览器使用的是UTF-8编码。
通过浏览器的地址栏或通过浏览器的XMLHttpRequest发送的GET请求参数,都会自动被浏览器内部进行编码。
POST请求方法的作用是 创建 | | 更新。
POST请求参数一般放在请求体中,而不是放在URL中。
早期POST请求方法主要用来提交网页中表单数据,后面出现了ajax,所以可以脱离表单发送POST请求。
POST用于提交表单数据时,通常会将请求体中的数据进行url encode编码,和上面GET类似,也是由浏览器自动完成的。
HTTP响应状态码范围:001~999,可以自定义状态码
HTTP协议规定了一些标准状态码,主要分为以下几类
状态码类型 | 说明 | 常见码值 | |
1XX | Informational信息性状态码 | 代表请求已被接受,需要继续处理。这类响应是临时响应,只包含状态行和某些可选的响应头信息,并以空行结束 | 100 |
2XX | Success 成功状态码 | 代表请求已成功被服务器接收、理解、并接受 | 200,204,206 |
3XX | Redirection 重定向状态码 | 代表需要客户端采取进一步的操作才能完成请求。通常,这些状态码用来重定向,后续的请求地址(重定向目标)在本次响应的 Location 域中指明 | 301,302,304 |
4XX | Client Error 客户端错误 | 请求存在问题,服务器无法处理 | 400,403,404 |
5XX | Server Error 服务器错误 | 服务器处理请求过程中发送错误 | 500,502,503 |
HTTP请求和响应报文都有报文头,其中的报文头中字段可以分为三类:
通用报文头字段(请求响应都有)
专用报文头字段(请求或响应独有)
自定义报文头字段(通常用来配合服务器的功能)
在通用报文头字段中还可以解耦出一个:实体报文头字段,即专门用于描述请求体的报文头字段
图片来源:2小时玩转HTTP协议核心知识 编程 测试开发 网络知识 爬虫_哔哩哔哩_bilibili
HTTP无状态特性 是指两台主机之间每次发送的HTTP请求都是独立的,没有关联的。
比如 沈腾 给 大爷 发了一条HTTP请求(你好,我找马冬梅),大爷回复了一条HTTP响应(什么冬梅???)
沈腾 耐着性子 又给大爷 发了一条 HTTP请求(马~冬梅啊),大爷回复了一条HTTP响应(马什么梅啊???)
沈腾 抱着最后一次希望给大爷 再次发了一条HTTP请求(马~冬~梅 啊),大爷回复一条HTTP响应(马冬什么???)
沈腾......
沈腾像一台客户端,大爷就像一台服务器,但是这台服务器不会记录别人发的请求信息中的重要数据,而HTTP协议就像沈腾和大爷的交流过程,这个交流过程只负责传递消息,绝也不会帮服务器去记录请求信息,所以在大爷看来,沈腾每次问的问题都是一个新问题。
而HTTP无状态性有好处,也有坏处:
好处是,大爷处理问题的速度很快,他不会真的在大脑中检索马冬梅,而是每次都在确认找谁?
坏处是,沈腾惨了,每次问问题都要带上参数“马冬梅”。
在实际业务中,HTTP无状态性主要影响了身份认证。
比如,比如某个网站需要登录后才能访问网页。我们进入网站后,进行登录操作,然后访问了登录后页面A,然后我们还需访问页面B,但是到了B页面,由于HTTP无状态性,每次HTTP请求都是独立的,导致前面的登录结果无法保留下来,所以我们已经没有了登录证明,即无法访问到B页面。
所以导致了我们每访问一个页面就要重新登录一次,以获得登录证明,给当前页面。
所以HTTP无状态给身份认证结果的延续性带来了挑战。
而在不改变HTTP协议特性的前提下,出现了很多解决HTTP协议下身份认证结果延续性的方案,其中最具有代表性,最常用的有三个:
Cookie,Seesion,Token