在之前的项目里经常使用到HTTP,但是嘞,又没有很“经常”。这关系到HTTP一个特点,即“一次配置,终身使用”。
很多时候我们本根不需要去关注他怎么写,在公司或者其他组织里只要有相关的规范或者说是框架,那么里面有关HTTP的部分就是已经写好的,不管你能不能理解,只要照着别人写过的例子你就会使用。但这种会使用还真就不是说也一定能讲清楚http。近期面试就有一个很大的感触,面试官问到有关HTTP的内容时,可以将几句,但是问深了,问到一些不经常使用的内容就还是会迷糊。
所以这里是在做一篇有关于HTTP的整理,会讲到什么是HTTP、HTTPS为什么是安全的、“长连接”“连接”是什么、什么是用JSON传数据。
什么是HTTP?
通常我们见到的HTTP就两个地方:
一是浏览器地址栏输入的地址
http(协议类型)://baidu.com(服务器地址)/user?gender=male(路径path);
二是Android里发送网络请求,返回对应内容这个过程。
官方的解释是:HTTP是一种超文本传输协议(Hypertext Transfer Protocol)
翻译过来就是:在两个端之间传输字符、图片、声音等信息的一种网络规范(协议)
也就是浏览器到服务器之间的一个过程
三次握手(连接),四次挥手(断开)
不多说,懂的都懂,直接看图(这里怎么去清楚的讲给面试官听,留了一个自由发挥的空间,注意要简洁明了)
连接过程
断开过程
HTTP的报文
报文包括: 请求行/状态行、Header、body(body可以有可无)
请求报文
请求方法
所有请求方法的响应都有Body,HEAD除外
GET 请求资源;没有Body(请求body)
书写格式,例:
@GET(“users/{id}”)
Call<User> getUser(@path("id") String userId);
POST 修改或删除资源,有Body
PUT 修改资源,有Body
DELETE 删除资源,有Body
HEAD 获取信息(与GET请求一样,不同的是:响应没有Body)
正常情况下GET请求是不会有Body的,有些公司的程序员会在GET请求里带Body,这是一种错误的写法,不规范。
如果后台非要在GET里面带Body,那么上述的GET请求应改为:
@GET("users")
Call<User> getUser(@Body String userId);
除此之外,还应该在Retrofit里面添加对字符串的支持(因为Body本身不支持字符串)
如果后台非要在GET请求里面带Body,在Retrofit里面没有加Body(不能有Body的注解)就有可能出现这个报错(参数不对):
这种情况最好是联系后台让后台改接口(当然也会有方法解决,但是Android端做起来很麻烦)
另外,GET、PUT、DELETE请求都是幂等的(*幂等:多次调用不变)。
响应报文
状态码
响应状态码的作用在于,让程序员在开发过程中快速定位到问题所在,方便调试
状态码 | 含义 | 举例 |
1xx | 消息(临时消息) | 100:继续发送、101:正在切换协议 |
2xx | 成功 | 200:获取成功、201:创建成功 |
3xx | 重定向 | 301:资源永久迁移、302:资源临时迁移、304:内容未改变 |
4xx | 客户端错误(请求本身错误) | 400:客户端请求错误、404:资源不存在、401:认证失败、资源未授权 |
5xx | 服务器错误(内存不足) | 500:内部服务器错误、501:未实现(不支持)、502:错误的网关、503:服务无法获得、504:网关超时、505:不支持的Http版本 |
*重定向:原地址的东西在另一个地址
例:100 继续
如果服务器收到头信息中带有100-continue的请求,是客户端在问服务器后续的请求中是否可以发送附件。服务器用100(SC_CONTINUE)允许客户端继续或用417 (Expectation Failed)告诉客户端不同意接受附件
例:101 切换协议
当一个 询问可以使用http2吗?如果回复101表示http2也可以用,如果回复200表示不能使用http2
例:200 正常
200 (SC_OK)的意思是一切正常。一般用于相应GET和POST请求。这个状态码对servlet是缺省的;如果没有调用setStatus方法的话,就会得到200。
例:201 已创建
201 (SC_CREATED)表示服务器在请求的响应中建立了新文档;应在定位头信息中给出它的URL。
例:202 接受
202 (SC_ACCEPTED)告诉客户端请求正在被执行,但还没有处理完。
例:203 非官方信息
状态码203 (SC_NON_AUTHORITATIVE_INFORMATION)是表示文档被正常的返回,但是由于正在使用的是文档副本所以某些响应头信息可能不正确。
例:204 无内容
在并没有新文档的情况下,204 (SC_NO_CONTENT)确保浏览器继续显示先前的文档
例:301 资源永久迁移
当我们输入某链接为http开头时,浏览器会使用将http自动转为https,这时可以看到响应状态码为301,表示这个http里的内容永久转移到https上了。
例:400 客户端错误
400 (SC_BAD_REQUEST)指出客户端请求中的语法错误
例:401 未授权
401 (SC_UNAUTHORIZED)表示客户端在授权头信息中没有有效的身份信息时访问受到密码保护的页面
例:403 禁止
403 (SC_FORBIDDEN)的意思是除非拥有授权否则服务器拒绝提供所请求的资源。这个状态经常会由于服务器上的损坏文件或目录许可而引起
例:500 内部服务器错误
500 (SC_INTERNAL_SERVER_ERROR) 是常用的“服务器错误”状态。该状态经常由CGI程序引起也可能由无法正常运行的或返回头信息格式不正确的servlet引起
例:501 未实现
501 (SC_NOT_IMPLEMENTED)状态告诉客户端服务器不支持请求中要求的功能。例如,客户端执行了如PUT这样的服务器并不支持的命令
例:502 错误的网关
502 (SC_BAD_GATEWAY)被用于充当代理或网关的服务器;该状态指出接收服务器接收到远端服务器的错误响应
Header(HTTP消息的元数据 metadata)
Host : 服务其地址(目标主机地址)
DNS查询(Domain Name System 域名)
DNS服务器询问 api.github.com的IP地址是多少,服务器回复这个IP地址给浏器。
Content-Length : 内容的长度(字节)
给出这个长度是说明要读取Body里面的多少个字节,因为Body的类型有很多种,如果以\n来读取的话,当碰到Body信息本身就含有\n的地方时就会停止读取,这样会导致信息丢失。
Content-Type : 内容的类型
text/html : html文本,浏览器页面响应
application/x-www-from-urlencoded : 普通表单(即纯文字表单),encoded URL 格式
multipart/from-data :多部分形式,一般用于传输包含二进制的多项内容(图片、文件等)
普通表单里只有文字,可以用&划分(因为boundary很长浪费空间,这里不需要使用)
application/json : json形式,用于Web api响应或POST、PUT请求
iamge/jpeg/application/zip... : 单文件,用于Web api响应或POST、PUT请求
域名是给人类看的,并不能找到该网页,通过IP地址才能找到网页(DNS将域名换成IP地址)
Cache:缓存
Buffer:缓冲
HTTPS为什么是安全的?
HTTPS = HTTP + SSL / TLS (SSL是TLS的前身)
HTTPS没有版本号,它并不是一个更高级的协议,而是在HTTP下增加的一个安全层,用来保障HTTP的加密传输的。
--> 本质上是在客户端和服务端之间用非对称加密协商出的一套对称密钥,每次发送信息之前将内容加密,收到信息后再解密,是内容加密传输。
为什么不直接使用非对称加密?
因为非对称加密速度太慢了,里面使用了很多复杂的数学原理计算非常复杂,完全使用非对称加密会影响网络通信的性能。
但是非对称加密更安全,所以先用非对称机密去协商一个对称加密的密钥,后面再完全使用对称加密。(这样可以保证安全性和性能)
HTTPS的连接
1.客户端请求建立TLS的连接
首先客户端发一个单字节数据(client hello)与服务器打招呼,并提供所支持TLS版本的集合和加密套件(即,可选的对称、非对称的加密算法hash算法),客户端随机数(本地会保留一份);
2.服务器发回证书
服务器也发送一个单字节数,并选出TLS的版本和加密套件回复给客户端(servers hello),服务器随机数(本地会保留一份);服务器把证书发给客户端(服务器公钥)
3.客户端验证这个证书
4.客户端信任服务器之后与服务器协商对称密钥
客户端发送根据服务器的公钥生成的加密随机数(pre-master secret),
5.使用对称密钥开始通信(客户端)
注释:证书只能证明这是我的证书,不一定表示合法
6.finished
7.使用加密通信(服务器)
8.finished
另外的一些补充信息:
HTTPS的连接是用于加密和解密的;
HTTPS不负责数据的稳定传输,数据的稳定传输是由TCP负责的
HTTPS需要用到SSL证书,而HTTP不用;
HTTPS标准端口443,HTTP标准端口80;
HTTPS基于传输层,HTTP基于应用层;
“长连接”“短连接”是什么?
定义
短连接:
在三次握手之后建立连接,发送数据包并得到服务器返回的结果之后,通过客户端和服务端的四次握手进行关闭断开
长连接:
执行三次握手链接后,不断开链接,保持客户端和服务端通信,直到服务器超时自动断开链接,或者客户端主动断开链接
HTTP1.0中默认使用短连接
HTTP1.1中使用长连接。
使用长连接的HTTP协议,会在响应头加入这行代码:
Connection:keep-alive
HTTP的长连接、短连接实际还是TCP的长连接】短连接
优缺点
短连接由于三次握手链接及四次握手断开,在请求频繁的情况下,链接请求和断开请求的开销较大会影响效率
使用场景
长连接:客户端和服务端通信很频繁的场景,比如:聊天室、实时的游戏
短连接:网页浏览等数据刷新率低的时候
什么是用JSON传数据?
Json优点
1.数据格式比较简单, 易于读写, 格式都是压缩的, 占用带宽小
2.易于解析这种语言, 客户端JavaScript可以简单的通过eval()进行JSON数据的读取
3.因为JSON格式能够直接为服务器端代码使用, 简化了服务器端和客户端的代码开发量, 但是完成的任务不变, 且易于维护
JSON语法
语法规则
数据在名称/值对中
数据由逗号分隔
花括号保存对象
{"key":value"}==>key=value 因为是字符串所以用双引号
方括号保存数组
键值对
JSON 数据的书写格式是:{Key:Value}、{Key:Array}。
注意:如果是字符串则需要用引号
例如:{"name" : "晋二"}等价于js语句的name="晋二"
JSON数据结构中的value的取值:
string(双引号中)、number、object(花括号中)、array(方括号中)、boolean(true/false),null
{
"type1": "string",
"type2": 31,
"type3": {"name":"王五"},
"type4": ["张三","李四"],
"type5": true,
"type6": null,
}
一般前后端传递数据用的是键值对的方式就是JSON传数据了,另外,fastjson在序列化和反序列化这方面非常方便,可以试试。