Android APP开发实战:从规划到上线全程详解
上QQ阅读APP看书,第一时间看更新

第6章 HTTP网络请求

6.1 HTTP简介

6.1.1 协议

HTTP协议即超文本传送协议(HyperText Transfer Protocol),是APP连接服务器使用最多的协议。

HTTP连接最显著的特点是客户端发送的每次请求都需要服务器回送响应,在请求结束后会主动释放连接。从建立连接到关闭连接的过程称为“一次连接”。

在HTTP 1.0中,客户端的每次请求都要求建立一次单独的连接,在处理完本次请求后,就自动释放连接;在HTTP 1.1中则可以在一次连接中处理多个请求,并且多个请求可以重叠进行,不需要等待一个请求结束后再发送下一个请求。

HTTP协议采用了请求/响应模型,即客户端向服务器发起请求,然后服务器返回结果数据,客户端解析结果数据后,再把数据展示给用户。

6.1.2 HTTP方法

1.方法

HTTP 1.1协议中常用的有以下几种方法。

(1)OPTIONS

返回服务器针对特定资源所支持的HTTP请求方法。也可以利用向Web服务器发送’*’的请求来测试服务器的功能性。

(2)HEAD

向服务器索要与GET请求相一致的响应,只不过响应体将不会被返回。这一方法在不必传输整个响应内容的情况下,就可以获取包含在响应消息头中的元信息。

(3)GET

向特定的资源发出请求。

(4)POST

向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新资源的建立或已有资源的修改。

(5)PUT

用于更新某个资源较完整的内容,比如说用户要重填表单,更新所有信息。注意PUT只对已有资源进行更新操作。

(6)DELETE

请求服务器删除Request-URI所标识的资源。

(7)TRACE

回显服务器收到的请求,主要用于测试或诊断。

(8)PATCH

用于资源部分内容的更新,例如用户信息中包含电话号码和其他字段,可以使用PATCH方法只更新电话号码字段内容。当资源不存在的时候,PATCH可能会去创建一个新的资源。

2.GET与POST的区别

在HTTP方法中,GET和POST是用得最多的两种方法。大多数APP只使用这两种方法,有些甚至只使用POST方法。

GET与POST两种方法的区别如下所述。

· GET通常用于从服务器上获取数据,POST用于向服务器传送数据。

· POST通常比GET传送的数据量大。

· GET方法提交的数据放置在URL或头字段中,而POST提交的数据则放在BODY体中,比使用GET方法安全。

在既可以使用GET方法,也可以使用POST方法的情况下,从安全的角度考虑,建议使用POST方法。

6.1.3 HTTP消息

HTTP消息包括客户端发给服务器的请求消息(Request)和服务器发给客户端的响应消息(Response)。这两种类型的消息由一个起始行、一个或者多个头字段、一个指示头字段结束的空行和可选的消息体组成。

1.请求消息

请求消息的格式如下:

                        Request-Line
                        *(( general-header
                        | request-header
                        | entity-header ) CRLF)
                        CRLF
                        [ message-body ]

第一行为下面的格式:

        Method SP Request-URI SP HTTP-Version CRLF

· Method表示对于Request-URI完成的方法,这个字段是大小写敏感的,包括OPTIONS、GET、HEAD、POST、PUT、DELETE和TRACE等方法。

· SP表示空格。

· Request-URI遵循URI格式,当此字段为星号(*)时,说明请求并不用于某个特定的资源地址,而是用于服务器本身。

· HTTP-Version表示支持的HTTP版本,例如为HTTP 1.1。

· CRLF表示换行回车符。

· 第一行和空行之间是头字段区域,包含通用头字段、请求头字段和实体头字段。

· 最后一部分是消息体,对于APP使用最多的两个方法,GET方法是没有消息体的,POST方法有消息体。

请求消息示例:

        //请求行
        GET /app_api/session/authenticate HTTP/1.1
        //头字段区域
        Host: www.xjbclz.com
        Connection: keep-alive
        Cache-Control: no-cache
        Content-Type: application/json
        //利用头字段传递参数给服务器
        userName: xjbclz
        password: 123456
        User-Agent:  Mozilla/5.0  (Windows  NT  6.1;  WOW64)  AppleWebKit/537.36
    (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36
        Postman-Token: 5527afec-5280-eae3-0aae-0de41e931a94
        Accept: */*
        Accept-Encoding: gzip, deflate, sdch
        Accept-Language: zh-CN, zh; q=0.8, en; q=0.6
        Cookie: session_id=800564826bb38ebc52da95aa7a55c8cf5af62a67

以上为GET方法,没有消息体。下面是POST方法,有消息体。

        //请求行
        POST /app_api/session/authenticate HTTP/1.1
        //头字段区域
        Host: www.xjbclz.com
        Connection: keep-alive
        Content-Length: 165
        Cache-Control: no-cache
        Origin: chrome-extension://fhbjgbiflinjbdggehcddcbncdddomop
        Content-Type: application/json
        User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36
        (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36
        Postman-Token: 972eb99a-3c40-1250-7cf1-89ecabca995e
        Accept: */*
        Accept-Encoding: gzip, deflate
        Accept-Language: zh-CN, zh; q=0.8, en; q=0.6
        Cookie: session_id=800564826bb38ebc52da95aa7a55c8cf5af62a67
        //消息体
        {
            "params":{
                "useName":"xjbclz",
                "password":"123456"
            }
        }

2.响应消息

响应消息的格式如下:

                        Status-Line
                        *(( general-header
                        | response-header
                        |entity-header)CRLF)
                        CRLF
                        [ message-body ]

第一行为下面的格式:

        HTTP-Version SP Status-Code SP Reason-Phrase CRLF

· HTTP-Version表示支持的HTTP版本,例如为HTTP 1.1。

· Status-Code是一个三个数字的结果状态码。Reason-Phrase给Status-Code提供了一个简单的文本描述。Status-Code主要用于机器自动识别,Reason-Phrase主要用于帮助用户理解。

· 第一行到空行之间是头字段区域,包含通用头字段、响应头字段和实体头字段。

· 最后一部分是消息体。

响应消息示例:

        //状态行
        HTTP/1.1400 BAD REQUEST
        //头字段区域
        Server: Tengine
        Date: Sun, 19 Feb 2017 07:32:36 GMT
        Content-Type: text/html
        Content-Length: 137
        Connection: keep-alive
        //消息体
        <! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
        <title>400 Bad Request</title>
        <h1>Bad Request</h1>
        <p>Invalid JSON data:  ' '</p>

6.1.4 HTTP头字段介绍

HTTP的头字段包括通用头、请求头、响应头和实体头4种类型。

每个头字段由一个字段名、冒号(:)和字段值3部分组成,且字段名与大小写无关。

用户也可以在请求头字段区域或响应头字段区域添加自己定义的头字段。

1.通用头字段

通用头字段指客户端发送的请求消息和服务器端的响应消息都支持的头字段,包含如下字段。

(1)Cache-Control

Cache-Control是指定请求和响应遵循的缓存机制。在请求消息或响应消息中设置Cache-Control并不会修改另一个消息处理过程中的缓存处理过程。请求时的缓存指令包括no-cache、no-store、max-age、max-stale、min-fresh、only-if- cached,响应消息中的指令包括public、private、no-cache、no-store、no-transform、must- revalidate、proxy-revalidate、max-age。

各个消息中的指令含义如下所述。

· Public指示响应可被任何缓存区缓存。

· Private指示对于单个用户的整个或部分响应消息,不能被共享缓存处理。这允许服务器仅仅描述当前用户的部分响应消息,此响应消息对于其他用户的请求无效。

· no-cache指示请求或响应消息不能缓存。

· no-store用于防止重要的信息被无意发布。在请求消息中发送将使得请求和响应消息都不使用缓存。

· max-age指示客户端可以接收生存期不大于指定时间(以秒为单位)的响应。

· min-fresh指示客户端可以接收响应时间小于当前时间加上指定时间的响应。

· max-stale指示客户端可以接收超出超时期间的响应消息。如果指定max-stale消息的值,那么客户端可以接收超出超时期指定值之内的响应消息。

APP如果需要对从服务器获取的数据做缓存处理,可能就会用到Cache-Control的相关指令。

(2)Keep-Alive

Keep-Alive功能使客户端到服务器端的连接持续有效,当出现对服务器的后继请求时,Keep-Alive功能避免了重新建立连接。

对于提供静态内容的网站来说,这个功能通常很有用。但是,对于负担较重的网站来说,这里存在另外一个问题,虽然为客户保留打开的连接有一定的好处,但它同样影响了性能,因为在处理暂停期间本来可以释放的资源仍旧被占用。

(3)Date

表示消息发送的时间,时间的描述格式由rfc822定义,且描述的时间是世界标准时间,非本地时间。

(4)Pragma

用来包含实现特定的指令,最常用的是Pragma:no-cache。在HTTP 1.1协议中,它的含义和Cache-Control:no-cache相同。

(5)Host

指定请求资源的Intenet主机和端口号,必须表示请求URL的原始服务器或网关的位置。HTTP 1.1请求必须包含主机头域,否则系统会以400状态码返回。

(6)Referer

允许客户端指定请求URI的源资源地址,也允许废除的或错误的连接由于维护的目的被追踪。如果请求的URI没有自己的URI地址,Referer不能被发送;如果指定的是部分URI地址,则此地址应该是一个相对地址。

(7)Range

可以请求实体的一个或者多个子范围。

· 表示头500个字节:bytes=0-499

· 表示第二个500字节:bytes=500-999

· 表示最后500个字节:bytes=-500

· 表示500字节以后的范围:bytes=500-

· 第一个和最后一个字节:bytes=0-0, -1

· 同时指定几个范围:bytes=500-600,601-999

但是服务器可以忽略此请求头,如果GET请求包含Range请求头,响应会以状态码206(PartialContent)返回而不是以200(OK)返回。

APP如果做断点续传功能,需要设置Range的数值。

2.请求头字段

允许客户端向服务器传递关于请求或者关于客户端的附加信息。请求头字段包含以下字段。

(1)Accept

客户端告诉服务器自己接受什么介质类型,*/* 表示任何类型,type/* 表示该类型下的所有子类型,如type/sub-type。

(2)Accept-Charset

客户端申明自己可接收的字符集。

(3)Authorization

当客户端接收到来自服务器的WWW-Authenticate响应时,用该头部来回应自己的身份验证信息给服务器。

(4)Accept-Encoding

客户端申明自己接收的编码类型,通常指定压缩方法、是否支持压缩以及支持什么压缩方法(gzip, deflate)。

当设置类型为gzip时,服务器端会把数据按gzip方式进行压缩后再发送给APP,可以减少传输的数据量,从而减少用户的流量消耗。

(5)User-Agent

标示发出请求的用户类型。

3.响应头字段

允许服务器传递不能放在状态行的附加信息,这些字段主要描述服务器的信息和Request-URI进一步的信息,包含以下字段。

(1)Location

Location用于重定向接收者到一个新URI地址。

(2)Server

Server包含处理请求的原始服务器的软件信息。

4.实体头字段

请求消息和响应消息都可以包含实体(消息体)信息,实体信息一般由实体头字段和实体组成。

实体头字段包含关于实体的原信息,包括如下字段。

(1)Content-Type

用于向接收方指示实体的介质类型。

目前APP与服务器间传输的数据大多使用JSON格式,此字段的内容设置如下:

        “application/json; charset=utf-8”

(2)Content-Range

表示发送的实体数据的范围或位置,也指示了整个实体的长度。当服务器向客户端返回实体的部分数据时,必须描述响应覆盖的范围和整个实体长度。一般格式如下:

        Content-Range: bytes-unit SP first-byte-pos-last-byte-pos/entity-legth

例如,传送头500个字节字段的形式:Content- Range:bytes0-499/1234。其中Content- Range表示传送的范围。

(3)Content-Length

表示实体的整体长度。

(4)Last-modified

表示服务器上保存内容的最后修订时间。

6.1.5 Keep-Alive模式介绍

HTTP协议采用“请求—应答”模式,当使用普通模式,即非Keep-Alive模式时,每个请求/应答客户和服务器都要新建一个连接,完成之后立即断开连接;当使用Keep-Alive模式(又称持久连接、连接重用)时,Keep-Alive功能使客户端与服务器间的连接持续有效,当出现对服务器的后继请求时,Keep-Alive功能避免了建立或者重新建立连接,传输性能更高效。

HTTP 1.0中默认是关闭Keep-Alive模式的,需要在HTTP头加入“Connection: Keep-Alive”,才能启用Keep-Alive; HTTP 1.1中默认启用Keep-Alive模式,在HTTP头加入“Connection: close ”才可关闭。

6.1.6 HTTP状态码简介

HTTP的状态码分为如下5种类型。

· 1xx:信息响应类,表示接收到请求并且继续处理。

· 2xx:处理成功响应类,表示动作被成功接收、理解和接受。

· 3xx:重定向响应类,为了完成指定的动作,必须接受进一步处理。

· 4xx:客户端错误,客户请求包含语法错误或者是不能正确执行。

· 5xx:服务端错误,服务器不能正确执行一个正确的请求。

常见状态码的含义如下所述。

· 200 OK:服务器端收到客户端的请求后,正常处理完成客户端的响应,并把结果返回给客户端。

· 400 Bad Request:客户端请求的语法或参数有误,当前请求无法被服务器理解执行。

· 401Unauthorized:客户端的请求未经授权,这个状态码必须和WWW-Authenticate字段一起使用。

· 403 Forbidden:服务器已经理解客户端的请求,但是拒绝执行它。

· 404 Not Found:请求失败,请求所希望得到的资源未在服务器上发现,如客户端发起请求的URL不对。

· 500 Internal Server Error:服务器遇到了一个未曾预料的状况,导致它无法完成对请求的处理。

· 502 Bad Gateway:作为网关或者代理工作的服务器尝试执行请求时出错。