Android 网络编程(http协议)

2019-05-19  本文已影响0人  zerohdq

简介

特点

  1. C/S模式,快递员服务于客户。
  2. 简单:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST,每种方法规定了客户与服务器联系的类型不同。就相当于告诉快递员你的地址(路径)和你要的运输的方式(请求方法),比如我家住安卓小区你给我空运过来。。。
  3. 快速:由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。
  4. 灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。
  5. 无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。但是这种方式在请求频繁的条件下,将会在建立和断开连接上花费大部分时间,所以在1.0、1.1持久连接变为了默认连接方式,有兴趣的可以自己查一下这个方式。
  6. 无状态:HTTP协议是无状态协议,简单说就是健忘、没脑子。打电话给常年在小区送快递的快递小哥:“哥,还送老地方”,小哥:“你谁呀不认识!”,挂了。。。所以无状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。

URL 格式

http://host[":"port][abs_path]

如:http://blog.csdn.net:80/qijinglai
http表示要通过HTTP协议来定位网络资源;host表示合法的Internet主机域名或者IP地址;port指定一个端口号,为空则使用默认端口80;abs_path指定请求资源的URI(Web上任意的可用资源)。

Http报文

http报文可以分为请求报文和响应报文,格式大同小异。主要分为三个部分:

  1. 起始行
  2. 首部
  3. 主体

请求报文格式:

<method> <request-url> <version>
<headers>

<entity-body>

响应报文格式:

<version> <status> <reason-phrase>
<headers>

<entity-body>

从请求报文格式和响应报文格式可以看出,两者主要在起始行上有差异。这里稍微解释一下各个标签:

<method> 指请求方法,常用的主要是Get、 Post、Head 还有其他一些我们这里就不说了,有兴趣的可以自己查阅一下

<version> 指协议版本,现在通常都是Http/1.1了

<request-url> 请求地址

<status> 指响应状态码, 我们熟悉的200、404等等

<reason-phrase> 原因短语,200 OK 、404 Not Found 这种后面的描述就是原因短语,通常不必太关注。

method

HTTP请求方法有8种

  1. GET:请求获取Request-URI所标识的资源
  2. POST:在Request-URI所标识的资源后附加新的数据
  3. HEAD:请求获取由Request-URI所标识的资源的响应消息报头
  4. PUT: 请求服务器存储一个资源,并用Request-URI作为其标识
  5. DELETE :请求服务器删除Request-URI所标识的资源
  6. TRACE : 请求服务器回送收到的请求信息,主要用于测试或诊断
  7. CONNECT: HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。
  8. OPTIONS :请求查询服务器的性能,或者查询与资源相关的选项和需求

GET和POST的区别

两个方法之间在传输形式上有一些区别,通过Get方法发起请求时,会将请求参数拼接在request-url尾部,格式是url?param1=xxx&param2=xxx&[…]。
我们需要知道,这样传输参数会使得参数都暴露在地址栏中。并且由于url是ASCII编码的,所以参数中如果有Unicode编码的字符,例如汉字,都会编码之后传输。另外值得注意的是,虽然http协议并没有对url长度做限制,但是一些浏览器和服务器可能会有限制,所以通过GET方法发起的请求参数不能够太长。而通过POST方法发起的请求是将参数放在请求体中的,所以不会有GET参数的这些问题。
另外一点差别就是方法本身的语义上的。GET方法通常是指从服务器获取某个URL资源,其行为可以看作是一个读操作,对同一个URL进行多次GET并不会对服务器产生什么影响。而POST方法通常是对某个URL进行添加、修改,例如一个表单提交,通常会往服务器插入一条记录。多次POST请求可能导致服务器的数据库中添加了多条记录。所以从语义上来讲,两者也是不能混为一谈的。

状态码

状态代码有三位数字组成,第一个数字定义了响应的类别,且有五种可能取值:

常见的状态码如下:

header

在请求报文和响应报文中都可以携带一些信息,通过与其他部分配合,能够实现各种强大的功能。这些信息位于起始行之下与请求实体之间,以键值对的形式,称之为首部。每条首部以回车换行符结尾,最后一个首部额外多一个换行,与实体分隔开。

实体

请求发送的资源,或是响应返回的资源。

Http缓存

当我们发起一个http请求后,服务器返回所请求的资源,这时我们可以将该资源的副本存储在本地,这样当再次对该url资源发起请求时,我们能快速的从本地存储设备中获取到该url资源,这就是所谓的缓存。缓存既可以节约不必要的网络带宽,又能迅速对http请求做出响应。

先摆出几个概念:
新鲜度检测
再验证
再验证命中

我们知道,有些url所对应的资源并不是一成不变的,服务器中该url的资源可能在一定时间之后会被修改。这时本地缓存中的资源将与服务器一侧的资源有差异。

既然在一定时间之后可能资源会改变,那么在某个时间之前我们可以认为这个资源没有改变,从而放心大胆的使用缓存资源,当请求时间超过来该时间,我们认为这个缓存资源可能不再与服务器端一致了。所以当我们发起一个请求时,我们需要先对缓存的资源进行判断,看看究竟我们是否可以直接使用该缓存资源,这个就叫做新鲜度检测。即每个资源就像一个食品一样,拥有一个过期时间,我们吃之前需要先看看有没有过期。

如果发现该缓存资源已经超过了一定的时间,我们再次发起请求时不会直接将缓存资源返回,而是先去服务器查看该资源是否已经改变,这个就叫做再验证。如果服务器发现对应的url资源并没有发生变化,则会返回304 Not Modified,并且不再返回对应的实体。这称之为再验证命中。相反如果再验证未命中,则返回200 OK,并将改变后的url资源返回,此时缓存可以更新以待之后请求。

我们看看具体的实现方式:

新鲜度检测
我们需要通过检测资源是否超过一定的时间,来判断缓存资源是否新鲜可用。那么这个一定的时间怎么决定呢?其实是由服务器通过在响应报文中增加Cache-Control:max-age,或是Expire这两个首部来实现的。值得注意的是Cache-Control是http1.1的协议规范,通常是接相对的时间,即多少秒以后,需要结合last-modified这个首部计算出绝对时间。而Expire是http1.0的规范,后面接一个绝对时间。
再验证
如果通过新鲜度检测发现需要请求服务器进行再验证,那么我们至少需要告诉服务器,我们已经缓存了一个什么样的资源了,然后服务器来判断这个缓存资源到底是不是与当前的资源一致。逻辑是这样没错。那怎么告诉服务器我当前已经有一个备用的缓存资源了呢?我们可以采用一种称之为条件请求的方式实现再验证。
Http定义了5个首部用于条件请求:
If-Modified-Since
If-None-Match
If-Unmodified-Since
If-Range
If-Match

If-Modified-Since 可以结合Last-Modified这个服务器返回的响应首部使用,当我们发起条件请求时,将Last-Modified首部的值作为If-Modified-Since首部的值传递到服务器,意思是查询服务器的资源自从我们上一次缓存之后是否有修改。

If-None-Match 需要结合另一个Etag的服务器返回的响应首部使用。Etag首部实际上可以认为是服务器对文档资源定义的一个版本号。有时候一个文档被修改了,可能所做的修改极为微小,并不需要所有的缓存都重新下载数据。或者说某一个文档的修改周期极为频繁,以至于以秒为时间粒度的判断已经无法满足需求。这个时候可能就需要Etag这个首部来表明这个文档的版号了。发起条件请求时可将缓存时保存下来的Etag的值作为If-None-Match首部的值发送至服务器,如果服务器的资源的Etag与当前条件请求的Etag一致,表明这次再验证命中。

OAuth

OAuth是一个用于授权第三方获取相应资源的协议。与以往的授权方式不同的是,OAuth的授权能避免用户暴露自己的用户密码给第三方,从而更加的安全。OAuth协议通过设置一个授权层,以区分用户和第三方应用。用户本身可以通过用户密码登陆服务提供商,获取到账户所有的资源。而第三方应用只能通过向用户请求授权,获取到一个Access Token,用以登陆授权层,从而在指定时间内获取到用户授权访问的部分资源。

OAuth定义的几个角色:

Role Description
Resource Owner 可以授权访问某些受保护资源的实体,通常就是指用户
Client 可以通过用户的授权访问受保护资源的应用,也就是第三方应用
Authorization server 在认证用户之后给第三方下发Access Token的服务器
Resource Server 拥有受保护资源的服务器,可以通过Access Token响应资源请求
 +--------+                               +---------------+
 |        |--(A)- Authorization Request ->|   Resource    |
 |        |                               |     Owner     |
 |        |<-(B)-- Authorization Grant ---|               |
 |        |                               +---------------+
 |        |
 |        |                               +---------------+
 |        |--(C)-- Authorization Grant -->| Authorization |
 | Client |                               |     Server    |
 |        |<-(D)----- Access Token -------|               |
 |        |                               +---------------+
 |        |
 |        |                               +---------------+
 |        |--(E)----- Access Token ------>|    Resource   |
 |        |                               |     Server    |
 |        |<-(F)--- Protected Resource ---|               |
 +--------+                               +---------------+

从上图可以看出,一个OAuth授权的流程主要可以分为6步:

  1. 客户端向用户申请授权。
  2. 用户同意授权。
  3. 客户端通过获取的授权,向认证服务器申请Access Token。
  4. 认证服务器通过授权认证后,下发Access Token。
  5. 客户端通过获取的到Access Token向资源服务器发起请求。
    6.资源服务器核对Access Token后下发请求资源。

Https

简单的说 Http + 加密 + 认证 + 完整性保护 = Https

传统的Http协议是一种应用层的传输协议,Http直接与TCP协议通信。其本身存在一些缺点:

  1. Http协议使用明文传输,容易遭到窃听。
  2. Http对于通信双方都没有进行身份验证,通信的双方无法确认对方是否是伪装的客户端或者服务端。
  3. Http对于传输内容的完整性没有确认的办法,往往容易在传输过程中被劫持篡改。

因此,在一些需要保证安全性的场景下,比如涉及到银行账户的请求时,Http无法抵御这些攻击。
Https则可以通过增加的SSL\TLS,支持对于通信内容的加密,以及对通信双方的身份进行验证。

上一篇 下一篇

猜你喜欢

热点阅读