参考小林coding
HTTP基本概念
HTTP是超文本传输协议。所谓的超文本,就是超越了普通文本的文本,最关键的是有超链接,能从一个超文本跳转到另一个超文本。
HTML是最常见的超文本,本身是纯文字文件,但是内部使用很多标签定义图片、视频等链接,再经过浏览器的解释,呈现出来的就是一个由文字、画面的网页了。
HTTP是两点之间传输,可以是服务器到本地浏览器,也可以是服务器和服务器之间。
HTTP和HTTPS的区别
- HTTP是没有加密的,也就是明文的,所以HTTP很不安全;HTTPS使用SSL+HTTP协议,可以加密传输、身份认证,安全。
- HTTPS协议因为需要CA证书,一般免费证书比较少,需要一定费用。
- HTTP和HTTPS使用不同的连接方式,用的端口不一样:HTTP80,HTTPS443
HTTPS解决HTTP哪些问题?
窃听风险—混合加密
采用对称加密和非对称加密。通信建立前采用非对称加密(使用两个密钥,公钥和私钥),通信过程中使用对称加密。
篡改风险—摘要算法和数字签名
使用==摘要算法(哈希函数)==计算出内容哈希值,这个哈希值是唯一的:
我们对内容计算出一个“指纹”,连同内容一起传输给对方,对方收到之后,对内容也计算出一个“指纹”,跟发送方的“指纹”做一个比较,如果指纹相同,说明内容没有被篡改。
但是这种会出现(内容+哈希值)被中间人替换的风险。所以可以使用非对称加密算法来解决。
非对称加密算法
一个是公钥,一个是私钥。
- 公钥加密,私钥解密:保证传输内容安全,因为只有持有私钥的人,才能解密出实际内容。
- 私钥加密,公钥解密:保证消息不被冒充。因为私钥是不可以泄露的,如果公钥可以解密出私钥加密的内容,说明这个消息来源于持有私钥身份的人发送。
冒充风险—数字证书
如果公钥是被伪造的怎么办呢?可以引入数字证书。
在计算机里,有一个权威机构叫做CA(数字证书认证机构)。服务器的运营人员向CA提出公开密钥申请,CA 在判明申请者的身份之后,会对已经申请的公开密钥做出数字签名,然后分配这个已经签名的公开密钥,并将这个公开密钥放入公开密钥证书后绑定在一起。
进行HTTP通信的时候,服务器把证书发给客户端,客户端取得其中的公开密钥之后,先用数字签名进行验证,如果验证通过,就可以开始通信了。
HTTPS如何建立连接
SSL/TLS协议建立
基本思路就是采用公钥加密法,也就是说,客户端先向服务器端索要公钥,然后用公钥加密信息,服务器收到密文之后,用自己的私钥解密。
-
ClientHello:客户端向服务器发起加密通信请求。
发送支持的TLS版本,客户端产生的随机数(后续用于生成会话密钥),客户端支持的密码套件列表(RSA加密算法,是TLS 1.0版本的,现在流行的TLS 1.2已经称为主流) -
ServerHello:服务器收到客户端请求之后,向客户端发送响应。
回应内容包括确认TLS协议版本(如果浏览器不支持,关闭加密通信),服务器产生的随机数,确认的密码套件列表,服务器的数字证书 -
客户端回应:首先通过浏览器或者操作系统中的CA公钥,确认服务器数字证书的真实性,如果证书没有问题,客户端会从数字证书中取出服务器公钥,然后使用它加密报文。
向服务器发送一个随机数(这个随机数会被服务器公钥加密,这个随机数客户端和服务端都是一样的),加密通信算法改变通知(表示随后的信息都将用会话密钥加密通信),客户端握手结束通知,同时把之前所有内容的发生数据做个摘要,用来提供服务端校验。 -
服务器最后回应:服务器收到客户端第三个随机数之后,通过协商的加密算法(私钥),计算出本次通信的会话密钥。
然后向客户端发送最后的消息:前面三个随机数生成的对话密钥用来加密接下来的整个对话过程;加密通信算法改变通知,表示随后的信息都将用会话密钥加密通信;服务器握手结束通知,表示服务器握手阶段已经结束,同时把之前所有内容的发生的数据做个摘要用来给客户端提供校验。
HTTP状态码
1XX
客户端可以继续发送请求或者忽略这个相应
2XX
- 200:OK
- 204:请求成功,但是==返回的响应报文不包含实体的主体部分。
- 206:表示客户端进行范围请求,响应报文包含content -Range指定范围的实体内容
3XX
- 301:永久重定向
- 302:临时性重定向
- 303:临时性重定向,但是客户端应该采用GET方法获取资源
- 304:请求报文会包含一些条件,比如if-match,if-none-match,如果不满足条件,则返回304
- 307 :临时重定向,与302的含义类似,但是307要求浏览器不会把重定向请求的POST方法改成GET方法。
4XX
- 400:请求报文存在语法错误
- 401:这个状态码表示发送的请求需要有认证信息(BASIC认证,DIGSET认证)。如果之前已经进行过一次请求,则表示用户认证失败。
- 403:请求被拒绝
- 404:表示请求的资源在服务器上面不存在或者未找到,所以无法提供给客户端。
5XX
- 500:与400类似是一个笼统的错误码,服务器发生了什么 错误,我们并不知道
- 501:客户端请求的功能目前还不支持
- 502 Bad Gateway:服务器作为网关或者代理的时候返回的错误码,表示服务器自身工作正常,访问后端服务器发生错误。
- 503:表示服务器当前很忙,暂时无法响应客户端。
HTTP缓存
对于一些重复的HTTP请求,每次请求到的数据都是一样的,那么可以把这对请求响应的数据缓存在本地,那么下次就可以直接读取本地数据,不需要通过网络获取服务器响应。HTTP有两种缓存:强制缓存和协商缓存。
强制缓存
只要浏览器判断缓存没有过期,就直接使用浏览器的本地缓存,决定是否使用缓存的主动性在浏览器这边(from disk cache)。如果过期,就会重新请求服务器。服务器再次受到请求之后,会再次更新响应头部的Cache-Control。
强制缓存利用两个HTTP响应头部字段实现:Cache-Control和Expires。前者是一个相对时间,后者是绝对是件,前者的优先级高于后者。
协商缓存
某些请求的响应码是304,这个是告诉浏览器可以使用本地缓存的资源。通常这种服务端告知客户端是否可以使用缓存的方式被称为协商缓存。可以通过If-Modified-Since和If-None-Match来实现。参考小coding:
- ETag优先级更高的原因是没有修改文件内容就不用重新请求;而且If-Modified-Since能检查到的粒度是秒级的,使用Etag可以保证一些秒级修改以内的可以刷新;而且有的服务器不能精确获取文件最后修改时间。
禁用缓存和确认缓存
HTTP/1.1通过Cache-Control首部字段来控制缓存。通过no-store进行禁止缓存;通过no-chche指令规定缓存服务器需要先向源服务器验证缓存资源有效性,只有缓存资源有效的时候才能使用该缓存对客户端的请求进行响应。
HTTP请求
HTTP请求过程
- 域名解析
- 发起TCP3次握手
- 建立TCP连接之后发起http请求
- 服务器响应http请求,浏览器得到html代码
- 浏览器解析html代码,请求html中的资源
- 浏览器对页面进行渲染呈现给用户
HTTP请求方法
客户端发送的请求报文第一行为请求行,包含了方法字段。
图片来源阿秀的学习笔记
GET和POST区别
- GET的语义是从服务器获取指定的资源。
- POST是根据请求负荷(报文body)对指定资源作出处理。
- GET请求的参数一般是写在URL中,URL规定只支持ASCII,所以GET请求的参数只允许ASCII字符,而且浏览器会对URL长度有限制(2K,实际取决于浏览器和服务器。浏览器就不说了,服务器因为处理长URL需要消耗比较多的资源,为了性性能和安全会给URL长度加上限制)。(HTTP协议本身对URL长度没有规定)
- POST请求携带数据的位置一般是写在报文中,body中可以是任何格式的数据,只要客户端与服务端协商好就可以,而且浏览器一般不会对body大小作出限制。但是实际上POST所能传递的数据量取决于服务器设置和内存大小。一半POST数据量很少有超过MB的,因为上传文件的时候,如果要上传比较大的数据或者文件到服务器,有可能上传不上去。
安全性和幂等性
- GET是安全和幂等的。因为只读性,无论操作多少次,数据都是安全的。(可以对GET请求的数据做缓存,这个缓存可以放到浏览器上面或者代理比如nginx,还可以保存为书签)
- POST会修改数据所以不安全,多次提交数据就会创建多个资源,所以不是幂等的。
但是如果开发者不按照RFC规范语义来实现GET和POST方法,那GET和POST的安全性和幂等性就不能保证了
其实,从传输的角度来说,GET和POST都是不安全的,因为HTTP在网络上是明文传输的,只要在网络节点上面捉包,就可以完整的获取数据报文。要实现真正的安全传输,就只有加密,也就是HTTPS。
能否携带body
POST请求携带数据的位置一般是在body中,其实RFC规范并没有规定GET请求不能携带body,但是GET一般是用来获取资源的,所以不需要body。
产生TCP数据包
- GET产生一个TCP数据包
- POST产生两个TCP数据包,浏览器先发送header,服务器响应100continue;浏览器再发送data,服务器响应200ok。(但是在Chrome上面实际测试之后发现,header和body不会分开发送。这说明分开发送是部分浏览器或者框架的请求方法,不属于POST的必然行为。)
GET方法参数
在约定中,参数是写在?后面,用&分割。我们也可以自己约定参数,只要服务端可以解释出来就行。