HTTP请求复用TCP连接
问:与服务端建立HTTP连接后会断开TCP连接吗,下一次请求需要重新建立连接吗?
答:在HTTP1.0的时候建立HTTP连接后默认会断开TCP连接,除非在请求头设置COnnection=keep-alive,但是keep-alive需要服务器支持。在之后的HTTP1.1中默认支持长连接,除非请求头中设置Connection=close。
文章图片
一个TCP连接中HTTP连接可以一起发送吗
HTTP1.1存在一个问题,单个TCP连接同一时刻只能处理一个请求,意思是只能等到上一个请求相应了才能发送下一个请求。HTTP1.1使用了pipelining技术来解决这个问题,可以先发送所有的请求而不用等待相应,但是相应结果必须和请求的顺序一致,但是这样也会有一个问题就是后面的请求响应必须等到前面的响应完才能开始处理。这也称为队头阻塞
在测试中,请求1和请求2依次发送,请求1在服务端延迟2000ms才返回,按照这个pipelining理论,请求1返回结果之前请求2不应该得到响应,但实际上请求2的响应并未被阻塞,然后发现请求2单独建立了连接,发现是express的关系,测试发送两个请求1,发现第二次发送复用了第一次请求的建立的TCP并且第一次响应成功,第二次才响应,并且总共等待时间为4000ms,第二次请求等待第一次响应完才开始处理同一浏览器对同一host建立TCP连接数量有限制吗 有,HTTP1.1时代chrome一般是6个。
http1.0到1.1做的优化就是默认长连接和一个连接可以发送多个http请求 HTTP2 中使用多路复用技术解决同时发送请求的问题
文章图片
强缓存 ### 强缓存在命中缓存时不会重新发起请求,直接从浏览器获取缓存。
- Expires 设置缓存过期时间 http1.0的产物
- Cache-Control 设置缓存规则,取值可能是public,private,max-age,s-max-age,no-cache,no-store,http1.1的产物
- cahe-control优先级高于Expires
### 强制缓存失效后,会启用协商缓存 - Last-modified和if-modified-since 服务器响应返回Last-modified值为文件修改时间,当再次请求这个资源时,请求头会设置if-modified-since 值为Last-modified的值,如果没有区别会返回304和空的响应体。
- ETag和If-None-Match ETag是资源的唯一标识,由服务端返回,浏览器请求同一资源时,会将这个值放在If-None-Match中
- ETag是基于资源内容的,Last-modified是基于资源修改时间的,精度及优先级上ETag的方式更高。
### 实际如何使用缓存策略 - 对于频繁变动的资源,强缓存策略设置no-cache 不走强缓存,在通过ETag走协商缓存
- 对于不经常变动的资源,通过强缓存策略的max-age设置
文章图片
http1.1存在问题
- 线头阻塞 虽然可以同时发送多个请求,但是还是要等待上一个响应完了,再处理下一个响应
- http1同时发送多个请求,针对同一域名只能同时发送固定个数的请求,其他请求被阻塞,知道服务端有响应,其他请求才能真正被发出去,其他请求等待的时间就是stalled时间。
http2升级了什么 - 多路复用 用于解决线头阻塞问题,可以边响应边发送请求,不用等待,http2发送多个请求
- 二进制分帧 相对与http1.1的文本传输,二进制传输解析性能高效
- 头部压缩 同一个字段多次请求不会重复发送
文章图片
HTTPS HTTP通信存在的问题
- 内容为明文,容易被窃听
- 无法证明内容的完整性,容易被篡改
- 无法验证通信方的身份,容易被伪装
- 加密 :使用对称加密算法和协商密钥进行数据加密
- 完整性 : 基于散列函数验证信息的完整性
- 认证:使用非对称加密实现身份认证
加密的密钥和解密的密钥必须是同一个,没有密钥就无法解密,同理,只要有密钥谁都可以解密,但在互联网如何安全的传输密钥就是个问题
非对称加密
加密的密钥和解密的密钥不相同。解密方公开公钥,自己保存对应的私钥,加密方根据公钥加密内容,解密方用私钥解密内容。这个过程即使中间被人拦截内容,知道了加密算法,没有私钥也无法完成解密。参考求模运算。
完全使用非对称加密也无法解决完整性和安全问题,并且非对称加密性能低。
解决方式
HTTPS使用非对称加密传输对称加密的密钥,然后使用对称加密传输内。因此,对称加密的密钥无法被拦截,所以无法获得对称加密的密钥,因此保证了内容加密无法破解。
HTTPS如何解决 客户端先请求服务器的公钥PK,然后发送一个随机数num1,使用公钥加密后发送给服务端,服务端用自己的私钥解密拿到num1;之后的通信服务端和客户端通信都使用num1进行对称加密,因为num1只有客户端和服务端知道,中间被拿到了没有服务端的私钥就无法解密拿到num1。
但问题出在客户端需要先请求服务端的公钥,这个过程如何保证安全?
假如黑客中间拦截了请求,并向客户端发送了自己的公钥,然后客户端用黑客的公钥加密发送数据给黑客,黑客用自己的私钥进行解密,客户端实际上和黑客在通信。
问题就出在客户端请求服务端PK的过程可能会被伪造,所以要将请求PK的过程也加密。想办法不去请求PK,而是将PK内置到操作系统中。因此引入第三方CA证书,事先内置了第三方证书的PK。
服务端需要请机构给自己颁发lic,lic是CA将服务端的PK使用私钥加密后的结果。
现在,客户端请求服务端时,服务端返回CA颁发给自己的lic,客户端拿到lic后,可以使用CA的pk进行解密得到服务端的PK
这时候如果黑客在服务端返回lic时候拦截请求,即使可以通过CA的pk进行解密,如果试图修改服务端的PK但是没有CA的私钥无法对数据进行加密,这样就保证了PK无法被修改。
通过CA证书的方式就解决了身份认证的问题,使用非对称加密传输建立对称加密的密钥就保证了数据的加密。
但是现在能否保证数据不被篡改呢,或者是数据被篡改后客户端/服务端能够感知到,即保证数据的完整性?
答案是不行,黑客即使不知道内容,但还是可以随意修改数据包的内容,这样客户端/服务端就无法得到正确的数据包。
【HTTP2】这时候就需要散列函数,散列函数给传输内容生成一个数字签名