本篇文章基于HTTP/1.1的RFC 7231协议标准,介绍一些基本却必备的HTTP知识,主要包括URI、HTTP报文、请求方法、响应状态码、DNS域名。由于头字段包含的内容太多,比如条件请求、范围请求、缓存控制、代理等,下一篇文章专门讲解。
需要说明的是,协议标准好比接口,Okhttp或HttpUrlConncetion就是接口的具体实现,一般而言,实现会遵循接口的规则,但是也有可能修改甚至违背标准。
HTTP的定义
The Hypertext Transfer Protocol (HTTP) is a stateless application-level request/response protocol that uses extensible semantics and self-descriptive message payloads for flexible interaction with network-based hypertext information systems.
从协议标准的定义里面我们可以看到HTTP具备的一些特点:
- 无状态(stateless):指每个请求都是互相独立、毫无关联,协议不要求客户端或服务端记录请求相关的信息。
- 应用层(application-level):位于7层或4层网络分层模型的最上层,直接面向具体应用的协议。比如除了HTTP外,还有FTP、SMTP等
- 请求-应答(request/response):永远是请求方先主动发起连接和请求,而应答方只有在收到请求后才能答复,如果没有请求那不会有任何动作。
- 自描述信息(self-descriptive message):我们总是听说HTTP是明文传输,但其实是因为最开始的HTTP是通过明文传输,因此造成我们对HTTP传输信息的误解,其实从HTTP可以很方便的转换到加密传输这点来看,HTTP传输的是自描述信息。
- 不安全:不支持身份认证和完整性校验。同样,这点也是早期HTTP暴露出来的问题,不过可以通过扩展的HTTPS进行解决。
- 简单、灵活、可扩展:比如一开始只规定了报文的基本格式,后来增加了请求方法、版本号、状态码、头字段、TLS等,还可以添加任意功能。
URI 统一资源定位符
主要用于唯一地标记资源的位置或名字。
URI格式
- scheme:协议名,表示资源应该用哪种协议来访问,比如http、https、jar、file、ftp等等。
- : // :特定的符号,不能改变。
- user:passwd@:身份信息,表示登录主机时的用户名和密码,但现在已经不推荐使用这种形式了,因为它把敏感信息以明文形式暴露出来,存在严重的安全隐患。
- authority:包含host和port,表示资源所在的主机名host必须有,port可以省略,使用默认的端口号
- path:标记资源所在位置。
- query:URI的查询参数。
- #fragment:片段标识符,它是 URI 所定位的资源内部的一个“锚点”或者说是“标签”,浏览器可以在获取资源后直接跳转到它指示的位置,仅客户端使用。
- 一个完整的例子
http://www.baidu.com:8080/user?uid=1234&name=mario&referer=xxx
URI编码
HTTP协议要求对 ASCII 码以外的字符集和特殊字符做一个特殊的操作,把它们转换成与 URI 语义不冲突的形式,被称为"escape"和"unescape",俗称"转义"。
URI 转义的规则有点“简单粗暴”,直接把非 ASCII 码或特殊字符转换成十六进制字节值,然后前面再加上一个“%”。例如&