写点什么

详解 HTTP 协议

用户头像
Android架构
关注
发布于: 8 小时前

| 片段标识符 | 通常可标记出已获取资源中的子资源 | N |

无状态协议

Http 协议属于一种不记录状态的协议,即无状态协议,具体表现为,每次请求发起都会重新进行连接,并不会根据之前的状态或者持久化保持状态。每当有新的请求发送时,就会有对应的新响应产生。协议本身并不保留之前一切的请求或响应报文的信息。这是为了更快地处理大量事务,确保协议的可伸缩性。但是 Http 虽然是无状态协议,但是有保存状态信息的需求,HTTP1.1 开始引入了 Cookie 技术,使用 cookie 来代为管理状态信息。

HTTP 协议方法

Http 协议支持通过不同的请求类型--即协议方法来达成某种目的,实现功能,HTTP1.1 支持的协议方法如下:


GET :获取资源


Get 方法用来访问已经被 URI 识别的资源,指定的资源信息经由服务端解析以后返回对应的资源响应内容,也就是说如果当前访问的资源是文本等静态资源,则会返回对应的数据,如果是网关等程序,则会返回对应的结果。


POST:传输实体主体


在 HTTP 中推荐使用 POST 方法来传递我们需要传输的内容或者实体信息,虽然 GET 方法可以添加查询字符串来辅助传递一定的信息和参数,但是要注意的是 GET 方法定义仅仅是希望根据查询字符串来定位具体的资源,所以 GET 方法一般都希望得到快速响应,传递的数据的长度有一定的限制


PUT:传输文件


HTTP 协议中,PUT 方法被定义出来用来朝服务端传递文件(上传)使用的方法,要求在请求的报文中包含文件内容,然后保存文件到请求的 URI 所在的位置上,但是由于 HTTP1.1 不带有安全机制,所以一般当前方法在 HTTP 协议上不开放,类似的协议如:Restful 会开放实现其他规范的操作


HEAD:获得报文首部


HEAD 方法和 GET 方法一样,唯一的区别是 GET 方法返回完整的响应信息,而 HEAD 方法不需要报文主体部分,因为此方法仅用来获取头信息,用来确认 URI 是否有效或者触发资源的缓存更新等


DELETE:删除文件


DELETE 方法和 PUT 方法是完全相反的定义,这里的作用是用来删除指定请求 URI 上位置的资源文件,而和 PUT 一样,在不带有安全验证机制的情况下一般也是不开放的


OPTIONS:询问支持的方法


OPTIONS 方法使用场景比较特殊,一般情况下我们用来查询针对请求 URI 指定的资源支持的方法有哪些(和跨域操作也有一定的联系)


TRACE:追踪路径


TRACE 方法是 HTTP 协议用来检查和追踪请求过程提供的方法,当发送请求的时候,会在 Max-Forwards 首部填入数值,每次经过一个服务端就会-1,当数字减少到 0 的时候,就会停止传输请求,直到接受到返回的状态码响应才算结束。使用 TRACE 方法可以检查当前请求是否被篡改,但是由于当前方法很容易引起 XST(Cross-Site Tracing,跨站追踪)攻击,所以一般都禁止使用


CONNECT:要求用隧道协议连接代理


使用 CONNECT 方法要求是与代理服务器建立连接隧道,实现隧道间通信 TCP,常见会使用 SSL 或者 TLS 协议把内容加密后传递到隧道,CONNECT 的格式如下:


CONNECT 代理服务器名:端口号 HTTP 版本


我们把 1.0 和 1.1 两个版本的支持的协议方法列个表格,看下具体差异:


HTTP 报文

HTTP 通讯过程中用来交互传输数据的信息称之为报文,请求端发出的称之为请求报文,响应端的称之为响应报文,而 HTTP 的报文则是由多行字符串组合而成,其中回车符和换行符来区分每一个报文的内容及其属性以及报文首部和报文主体,报文整体组成大概如下:



从上图我们大概可以看出来报文整体通过空行拆分为报文首部和报文主体,并且请求报文和响应报文都是一样的结构,但是我们也可以看出来,请求报文和响应报文都包含通用首部字段和实体首部字段,而请求报文则是多了请求行和请求首部字段,响应报文则是在相同位置变成了状态行和响应首部字段,那么这些组成分别有什么作用呢?


请求行


首先请求行仅仅存在于请求报文中,用来记录当前发起请求的信息,比如 URI,请求方法,HTTP 版本等


状态行


状态行仅仅存在于响应报文中,内部记录了响应结果的状态码,成功/失败的原因说明,以及服务端返回的 HTTP 版本等


请求首部/响应首部/通用首部/实体首部


四种最常见的首部一般包含了请求/响应过程中各种属性及其对应的参数值,比如跨域请求,缓存过期时间等属性


其他首部


一般情况下 HTTP 内置的首部和组成是由上面的四种常见首部和请求行/状态行组成的,但是不要忘记,我们 H


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


TTP 可以配合 Cookie 等实现功能,其他首部中包含了其他的非 HTTP 规范定义的首部信息比如 Cookie 首部信息等

HTTP 首部

上面我们分析了报文的组成部分,其中有四个首部是最常见的首部,分别是请求首部、响应首部、通用首部和实体首部,那么我们看下四种首部分别是用来做什么的,以及 HTTP 规范给我们定义了那些首部字段:


通用首部


所谓通用首部,即请求报文和响应报文都可以配置的首部字段,一般都是超时时间、缓存等这些通用首部字段,HTTP 规范定义的通用首部字段共 9 个,如下:



请求首部字段


当客户端发起请求的时候特有的首部,可用来指定请求的方式,请求的策略等,HTTP 定义的请求首部字段共 19 个,如下:



响应首部字段


HTTP 交互过程中,服务端返回给客户端的时候使用的首部,包含服务端信息、重定向等,在 HTTP 中定义的有 9 种,如下:



实体首部字段


实体首部字段是 HTTP 交互过程中,为了传输实体而出现的属性配置,HTTP 指定了 10 种实体首部,如下:



而其中有部分首部在日常中经常使用,下面我们就看看几个常见的首部字段以及可选值:


Cache-Control:缓存行为控制


可用的值如下(请求):



可用的响应值如下:



Warning:错误信息通知


在 HTTP1.1 中定义的警告码如下:



Accept:用户代理可以处理的媒体类型


Accept 属性可以通知服务器,用户代理能接受/处理的媒体文件类型以及优先级,常见的如下:



其中 Accept 还可以指定优先级,使用 q=来额外表示权重值,用分号分割,权重范围 0-1,1 为最大值,可以为三位小数,不指定权重时默认 q=1.0


Accept-Encoding:优先的内容编码


Accept-Encoding 用来通知服务器用户代理支持的内容编码及优先级顺序,常见的编码如下:


HTTP 状态码

了解了 HTTP 的报文组成和组成 HTTP 请求/响应的首部信息,在完成了 HTTP 请求后,我们会根据响应报文来确定用户操作是否规范,而依据则是响应报文中很重要的一部分--HTTP 状态码


而在 HTTP 规范中,响应码以三位数的短数值和简要的信息表示,而三位数值的第一位数(百位数)决定了响应的类型,后两位数则是当前类型的具体子类型,目前 HTTP 中的 code 主要分为以下五种:



而这五大类型的具体子类在 RFC2616 上的 HTTP 状态码就达 40 种,后续扩展了数十种,而在我们开发过程中,绝大多数几乎见不到,所以接下来我们看看开发中能碰到的十来种常见的状态码


200:完全成功


当 HTTP 的返回码为 200 的时候,恭喜你,整个流程没有出现任何问题,完全成功!说明客户端的请求信息被服务端正常处理并且成功返回给了客户端


204:Not Content


当前的状态码代表客户端的请求已经被服务端处理完毕,并且服务端也给了响应信息,但是当前的返回信息中不包含响应信息主体


206:Partial Content


当前返回码比较特殊,因为只会出现在客户端的请求是部分范围请求并且成功响应的时候,比如报文中包含 Content-Range 进行部分范围请求的操作


301:Moved Permanently


当前响应码代表着请求的资源已经被永久性重定向,即我们请求的资源在服务端的 URI 已经变更,服务端期望我们使用 Loaction 首部字段等方式保存新的 URI 地址,后续使用当前 URI 进行访问


302:Found


当前响应码和 301 有类似的地方,即都是请求资源被重定向了,但是区别在于 301 是请求的资源 URI 的永久性移动变更,而 302 响应码代表着当前请求的时候这个资源的 URI 被变更了,但是这个变更只是临时的,仅仅本次请求期望使用变更后的 URI 请求


303:See Other


如果是 302 响应码是临时性 URI 变更的话,那么 303 就是 302 的升级版,因为 303 响应码拥有 302 响应码的全部功能,但是更严格的是,303 告诉你 URI 对应的资源中存在其他 URI,并且严格要求你使用 GET 方式去重新访问新的 URI


307:Temporary Redirect


303 作为 302 的升级版已经出现了,但是在严格程度上还远远不够,因为按照 HTTP 规范,302,303 的响应码都是希望用户不要把 POST 请求变为 GET,但是不能束缚浏览器或者用户行为,而 307 作为严格的执行者,只要响应了当前的 code,浏览器会遵照约定,不能把 POST 请求变成 GET 去访问资源


400:Bad Request


400 响应码可能是最诡异的响应码之一了,开发的过程中需要格外注意当前的响应码,因为当前响应码虽然是告诉我们报文请求中存在着语法错误,但是浏览器会按照 200 对待此响应


401:Unauthorized


当响应 401 响应码的时候,即代表服务端会发起质询的方式的一个认证请求,告诉我们需要进行认证才可以访问,这个时候我们需要将信息填写并确定才可以拿到具体的结果


403:Forbidden

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
详解HTTP协议