HTTP 基础篇

211 阅读8分钟

HTTP是什么?

HTTP是超文本传输协议,记住,只是一个协议

  • 超文本是什么呢?

超文本就是是用超链接的方法,将各种不同空间的文字信息组织在一起的网状文本

那么我们通俗一点来说呢,就是网页链接、超链接、包含了链接的文本,还有就是html

html也被称作超文本的,这里要说到一点http最初的作用就是用来传输html的

请求与响应格式

以下是大概的格式

  • 请求

在这里插入图片描述

大致的格式如上,一个请求报文包含请求行,请求头,请求体

请求行是由请求方法、路径、HTTP版本号组合而成,请求头与请求体后面解释了

  • 响应

在这里插入图片描述

响应报文与上类似,只不过响应行是由HTTP版本号、状态码、状态信息三个组合而成

HTTP的工作方式

浏览器为例:

1.浏览器发送请求给服务器

2.服务器给出响应

3.浏览器拿到响应后通过浏览器的渲染引擎渲染出来

渲染引擎就是浏览器的内核

HTTP常见的请求方法与状态码

  • 请求方法

GET:获取资源,没有Body,是HTTP0.9时唯一的请求方式;虽然说这里说的是没有body,但是你也可以加Body,但是不规范而已,并且在Retrofit中会报错;具有幂等性

POST:增加或修改资源,有Body;不具备幂等性

PUT:修改资源,有Body;具有幂等性

DELETE:删除资源;没有Body,它的path与GET类似;具有幂等性

HEAD:与GET一致,区别在于响应是没有Body的,它的实用场景在于提前获取某些信息,比如我要下载文件的时候,我可以先请求一次HEAD,通过返回的head我可以知道这个文件的大小,是否支持分段下载等等信息,然后我再根据这个信息去做进一步的操作

CONNECT:这个就是代理,将服务器做跳板,让服务器代替用户去执行真正的请求,然后把结果返回给用户,你百度的时候就会看到是用的这种请求方法

上面提到了幂等性,所谓的幂等性就是指每次执行相同的操作,结果都是一样的,比如说,我PUT修改的时候,我每次都是修改这条数据,他的结果都是一样的,GET也是,Post就不一样了,我每次新增一条数据,在数据库中的结果是不一样的,所以它不具备幂等性

  • 状态码

状态码一般区分为5个类别

1XX:临时性消息,有两个100与101;100表示继续发送请求,比如说客户端要上传一个较大的文件,但是不知道服务器是否愿意接它,所以就先询问下,如果服务器给你返回100,那么就是告诉你,你继续,我还能吃得下;101

2XX:成功,凡是2开头的都是请求成功的意思

3XX:重定向,head中会返回Location,Location就是真正的地址

4XX:客户端错误,常见的401,404这种,401未授权,404就是说你请求的地址不对,服务器找不到,其实我开始时候是想着,404诶,那不就是服务器没这个资源嘛,为什么算是客户端的问题呢?但是我后面想了下,你乱填服务器没有的地址,怎么能怪服务器呢?服务器也尽力找了,找不到呀

5XX:服务器错误,常见的500,这种一般就是后端代码报错了

Header与Body

  • header是什么?

    Header就是http消息的元数据

  • 元数据的概念

    元数据就是数据中的数据,对于http来说,他的核心数据是montch,path,body这些,但是还有一些数据是对这些核心数据起辅助作用的,比如说,你请求的数据有多长?数据的类型是什么?可接受的编码方式是什么?这些都是在header中去声明的,而这种在http请求数据中的数据,就是元数据

常见的一些Header
  • Host:这个是域名,比如baidu.com这种,他的作用就是让目标主机去定位子主机(同一主机上,可能存在不同的端口,或者说一个IP可以对应多个域名)

这里会有个误区,很多人都认为这个就是我们的服务器IP地址,其实不是的,我们的服务器地址是DNS根据域名去查询出IP地址来的,这里只是域名

  • Content-Length:请求体的字节长度或者响应体的字节长度,它的作用可以这么理解,我们的body是不能有结束符的,如果有结束符,那万一我的正常数据和结束符一样呢?那不就数据中断来呀,所以最好的办法就是直接告诉服务器我有多少字节,别瞎判断了

  • Content-Type:内容的类型;这个就有必要说道说道了,因为这个我感觉是我们Android比较在乎的一个点,以下为例如一些常见的并且做说明

    • text/html:html文本,用于浏览器响应,我们访问的网页,服务器给我返回的Content-Type就是这种格式的

    • application/x-www-form-urlencoded:普通表单(纯文字的表单),name=zhangsan&age=18这个形式的

    • multipart/form-data:多部分形式(就是有多项内容,比如我上传了图片,附带了图片信息数据),这种一般来说都是用在传输一些含二进制内容的多项内容(传文件之类的),他会有一个boundary去对你传输的多项内容进行分割,因为Content-length的大小计算是的总大小,她不知道你的每一项内容的大小应该是多少,普通表单是纯文字的可以通过&来分割,但是多项内容是不行的,因为它有的是文字,有的是二进制

      那么普通表单为什么不采用这种方式分割呢?

      其实道理很简单,效率呀!boundary太长了,你想象一下,明明我使用普通表单传输的数据是name=zhangsan&age=18,但是我如果要使用boundary来就是

      ------XADFGHTHHJFHUJNGFG.... Content-Disponstion:form-data;name="name"

      zhangsan ------XADFGHTHHJFHUJNGFG.... Content-Disponstion:form-data;name="age"

      18 ------XADFGHTHHJFHUJNGFG....

      这个样子的,你觉得爽么~

      boundary这个东西可能存在与我们的二进制重了(相等),这个时候就要重新发送请求了,但是这种重了的概率极小极小,几乎可以忽略不计

    • application/json:json形式的,用于Web Api的响应或者POST/PUT请求,{“name":"张三","age":18}这种格式

    • image/jpeg:单文件,用于Web Api的响应或者POST/PUT请求,这个一般来说我们都是用在下载文件的时候,上传文件的时候其实也可以使用这个,但是基本上没人用这种方式,因为大家都习惯了用multipart了,其实这种方式比multipart更加方便,更加效率,我们使用的时候比如说retrofit,我们直接对文件使用@Body注解,传入RequestBody,然后RequestBody的MediaType类型就是image/jpeg类型,这就行了

    Content-Type还有很多其他的类型,这里只列举了一些常见的,更多其他的可以自己查查看,继续我们的常见Header

  • Chunked Transfer Encoding:分块传输编码;这种一般用在请求结果比较大的时候,会严重影响前端渲染的时候,比如这个请求需要1秒,但是我们前端不可能等这个请求等1秒,我们要快速渲染出来,那么我们就可以和后端商量使用分块传输,每次我们获取一部分,就去渲染

  • Location:这个上面提及过,重定向的目标URL,一般状态码是3XX的时候

  • User-Agent:用户代理;其实就是指谁给服务器发的请求,是我们的浏览器,还是手机?当你用电脑浏览器打开网页的时候,Header中就有这个参数,写着你这是什么浏览器访问的,版本号是什么;这个参数呀,他是很有意义的,服务器会根据我们提供的这个参数知道我们是什么设备,然后根据我们不同类型的设备,返回给我们不同的内容,比如说浏览器的,那么他就会返回浏览器类型的数据,手机的就会返回手机类型的数据

  • Range/Accept-Range:指定Body的内容范围,如果后端支持Range,那么我们就可以在Header中添加Range去控制它的下载范围,这个我在之前写的断点续传的博客中用到了,这个的实用场景就是断点续传,多线程下载(某雷做法)这种

  • Accept:客户端能接受的类型,比如text/html

  • Accept-Charset:客户端能接受的字符集,比如说utf-8

  • Accept-Encoding:客户端接受的压缩编码类型

  • Content-Encoding:压缩类型

    ...

    还有很多Header这里就不一一列举了

RESTful

这个是什么呢?网上说是一种架构风格,但其实它就是正确的去使用HTTP,完全按钮HTTP的正确使用规范去用它,应该用GET的就用GET,应该用PUT的就用PUT,别乱搞