1. Http到底是什么

HTTP,Hypertext Transfer Protocol,超文本传输协议,与HTML(Hypertext Markup Language超文本标记语言)一起诞生,用于在网络上请求和传输HTML内容;Hyper 超 非super ,是扩展的意思
超文本,即扩展型文本,类似如下:
image.png

  • ⽤户输⼊地址后发起请求, 浏览器拼装 HTTP 报⽂并发送给服务器,服务器处理请求后发送响应报⽂给浏览器 ,浏览器解析响应报⽂并通过浏览器内核进行渲染显示(内核是浏览器的渲染引擎)
  • Android 代码调⽤拼装 HTTP 报⽂并发送请求到服务器,服务器处理请求后发送响应报⽂给⼿机,Android 代码处理响应报⽂并作出相应处理

请求报文
image.png
响应报文
image.png

2. 请求与响应

Request Method请求方法

1. GET

用于获取服务器资源,不对服务器资源进行修改,不发送Body,或者说使用GET方法传输Body是一种不规范的写法;(在Retrofit的GET方法中添加@Body属性,将会报错)

2. POST

POST主要用来增加或修改资源,有Body;
image.png

3. PUT

只用来修改资源,有Body;

那么问题来了,POST与PUT的区别是什么,在两者都可以使用的情况下应该用哪个更规范?

先回答后面问题:就比如在修改服务器资源的时候,其实两者都可以,和后端协同好,无论使用哪个都符合规范;POST与PUT的区别在于POST不具有幂等性,PUT具有幂等性;幂等是指多次操作的结果与一次操作的结果是一致的,GET也具有幂等性,因为取一次与取多次的结果是一样的

4. DELETE

用于删除资源,不发送Body,只需要锁定资源Id即可,也具有上文所说的幂等性

5. HEAD

与GET使用方法完全相同,唯一区别在于,返回的响应体终是没有Body的;它的作用主要是用于获取信息;比如在获取信息之前,先来一次HEAD,获取信息之后在去进行格外处理;

响应状态码Status Code

  • 1XX: 临时性消息;如100 (继续发送)、101(Http协议切换)
  • 2XX: 请求成功;如200(OK)、201(创建成功)
  • 3XX: 重定向;301(永久移动)、302(暂时移动)、303(内容未改变)
  • 4XX: 客户端错误;如 400(客户端请求错误)、401(认证失败)、403(被禁⽌)、404(找不到内容)
  • 5XX: 服务器错误;如 500(服务器内部错误)

3. Header首部

Header是Http消息的元数据,(可以理解为数据的数据,或者数据的属性,描述数据的相关信息)

Host

首先要明确的是,host不是用来在网络上寻址的,而是到达目标服务器之后用于定位子服务器的(倘若在一个主机上面运行了多个服务器)

DNS: 域名系统 Domain Name System

域名,例如www.baidu.com 是方便我们人去记住网络中的某个地址,但计算机是通过IP地址进行查找的,我们在请求域名的时候,会先请求DNS,DNS可以帮助我们将域名转换为相应的IP

Content-Type

指定Body的类型,主要有四类

1. text/html

代表Html网页类型数据

2. application/x-www-form-urlencoded (普通表单)

纯文字表单,类似下面这种键值对的形式
image.png

3. multipart/from-data

在含有多种类型文件时候的提交方式,例如普通文本加上 二进制文件时的提交方式,格式如下:
image.png
boundary是不同文件类型之间的分界线(普通表单使用boundary来分界,会造成带宽浪费),对应的Retrofit代码:

  1. @Multipart
  2. @POST("/users")
  3. Call<User> addUser(@Part("name") RequestBody name,@Part("avatar") RequestBody avatar);
  4. //RequestBody构建
  5. RequestBody namePart = RequestBody.create(MediaType.parse("text/plain"),nameStr);
  6. RequestBody avatarPart = RequestBody.create(MediaType.parse("image/jpeg"),avatarFile);
  7. api.addUser(namePart, avatarPart);

另外需要注意:

  • 使用普通表单加上base64来传递图片的行为是一种不合理的行为

4. application/json,image/jepg,application/zip…

单项内容,例如json格式,jepg类型格式,zip类型格式等等,类似如下
image.png

Content-Length

没什么可说的,表示body的字符长度,我们平时开发中看似也可有可无,那么它的主要作用是什么?
当我们传输的数据不是字符,而是二进制数据时,这个时候,我们没有办法去界定一个数据传输的结束,这个时候就可以使用字符长度来界定

分块传输 Chunked Transfer Encoding(只做了解)

分块传输是用在当我们发送数据请求时,服务端需要计算或者需要耗时操作才能返回数据(计算机中的时间优化是ms级别的),这个时候可以先返回一部分数据,让客户端先进行处理(当然,这个必须是在数据格式支持的情况下)
需要添加如下属性(具体使用方式,使用时再进行了解)

  • Transfer-Encoding:chunked

image.png

Cache(待完善)

  • Cache-Control:no-cache、no-store、max-age

这一块总计的有点乱,需要的话再去进行完善

cache与Buffer的区别

一个叫缓存,一个叫缓冲;缓存是暂时用过了,为了下次能够进行快速加载,节省资源性能,而将数据进行暂存的一种行为;缓冲是针对工作流的,用来处理上游生产过快,下游来不及消费或者下游即将进行爆发消费,上游先进行生产存在Buffer里的情况,例如网络请求爆发,路由器来不及处理,就会在Buffer里,路由器会不断地从Buffer里面取出请求进行操作

Cookie/Set-Cookie:发送Cookie/设置Cookie

待补充

Authorization

待补充

其他字段

  • Location 重定向地址(在301的时候拿到的Response中会有该字段),浏览器会自动获取该字段进行跳转
  • User-Agent 用户代理,客户端或者浏览器,网站会通过该字段确定是什么类型客户端(不重要)
  • Range/Accept-Ranges 分段加载,两个作用断点续传与多线程下载

在网站支持的前提下(在Reponse的Header部分有Accept-Ranges字段就是支持,该字段后面会跟一个值是数据类型),通过该字段可以加载链接的部分资源,在请求头中添加
Range:bytes=0-300 就是取从第0到300字节的数据

  • Content-Range:bytes 0-300/7098 分段加载时,会返回该字段,代表此次加载数据为从0到300字节,总长度7098字节
  • Accept: 客户端能接受的数据类型。如text/html
  • Accept-Charset: 客户端能接受的字符集。如utf-8
  • Accept-Encoding: 客户端能接受的压缩编码类型。如gzip
  • Content-Encoding: 压缩类型。如gzip

    4. RESTful HTTP

    首先要明确的是,RESTful HTTP是一种架构风格;

  • C/S架构

要明确一个概念,此处的C/S架构并不是狭义的客户端/服务器架构,浏览器也包括在内(C/S是一种真正的架构风格,B/S是为了区分客户端与浏览器才出现的一种说法,可以这么理解)

  • 无状态的 : 两个请求之间是没有关系的,客户端信息需要随请求携带
  • 可缓存的
  • 分层系统(Layered system): 当服务器不是一台主机,是一个集群时,对客户端来说应该是无感知的
  • Code on demand : 服务器可以返回可执行代码
  • 统一接口
    • 通过请求可以对资源进行确认
    • Resource manipulation through representations
    • 自描述的信息:数据可能是各种格式,需要在请求中描述信息类型
    • (HATEOAS) Hypermedia as the engine of application state : 大概理解为需要像网页一样提供一个页面去展示所有可查探的资源

来自扔物线的观点,RESTful Http是Http的最佳实践方法,两者是一种共生的关系,即规范使用Http就是RESTful HTTP;REST概念提出者对HTTP做了很大的贡献,很可能是在思考一种尽可能规范的C/S架构所衍生出来的产物;
包括以下几点:

  • 规范使用method来定义网络请求操作
  • 使用资源的格式来定义URL
  • 规范使用status code来表示响应状态
  • 其他符合HTTP规范的设计准则