http
###各种状态码
类别 | 原因 | |
---|---|---|
1xx | 信息性状态码 | 接收的请求正在处理 |
200 | 成功状态码 | 请求 |
204 | No Content | 请求处理完成,没有资源返回 |
206 | Partial Content | 进行了范围请求,服务器返回指定范围的内容 |
301 | Moved Permanently | 永久性重定向,请求的资源被分配到新的 URI 上 |
302 | Found | 临时性重定向 |
303 | See Other | |
304 | Not Modified | 直接使用缓存上的资源 |
400 | Bad Request | 请求报文中存在语法错误 |
401 | Unauthorized | 需要验证 |
403 | Forbidden | 无权限访问当前资源 |
404 | Not Found | 找不到当前资源 |
500 | Internal Server Error | 服务器内部或应用程序故障 |
503 | Service Unavailable | 当前服务器无法处理请求 |
3xx
重定向实际使用是一个响应码(301或302或303或307)和一个响应头location,当浏览器收到响应的时候check响应码是3xx,则会取出响应头中location对应的url
301:
301状态码在HTTP 1.0和HTTP 1.1规范中均代表永久重定向,对于资源请求,原来的url和响应头中location的url而言,资源应该对应location中的url。对于post请求的重定向,还是需要用户确认之后才能重定向,并且应该以post方法发出重定向请求
302:
在 HTTP1.1,当原请求是GET or HEAD方式的时候才能自动的重定向
303:
原请求是post,也允许自动进行重定向,结果是无论原请求是get还是post,都可以自动进行重定向
307:
如果重定向307的原请求不是get或者head方法,那么浏览器一定不能自动的进行重定向,即便location有url,也应该忽略
参考文章
- mdn
- http 图解
缓存
缓存控制
HTTP/1.1 通过 Cache-Control
区分缓存机制的的支持情况。 HTTP/1.0 则通过 Pragma
控制。
控制的类型:
no-store
禁止缓存每次都要从服务器下载整个响应内容
no-cache
强制确认缓存每次都要从服务器确认资源是否有过期,未过期则使用本地缓存
private
私有缓存该响应只能应用于浏览器私有缓存中
public
公有缓存该响应可以被中间人进行缓存(cdn,代理等)
max-age=<seconds>
表示资源可以被缓存多久(按秒算)
must-revalidate
缓存验证确认缓存在考虑使用一个陈旧的资源时,必须先验证它的状态,已过期的缓存将不被使用
Pragma
只有 no-cache
选项,效果一致。
如果设置了 max-age
或者 expires
,且有效没过期,就不会请求到服务器,从缓存里拿。如果 max-age
过期了,就会请求到服务器。
Last-modified/If-Modified-Since
与 Cache-Control
进行配合使用。如果 max-age
过期,服务器会判断 reuqest
头部的 If-Modified-Since
的时间值,和资源的最后修改时间是否一致,判断资源是否需要重新发送。
Etag
与 If-None-Match
配合使用,响应返回的 Etag
,再次请求该资源,会从 If-None-Match
带回来,然后服务器判断该字段,判断资源是否有修改过。
如果 http
请求返回了 304,response
是不会带任何东西的,浏览器会从缓存里拿,这样就节省了资源。
这里引用知乎,饿了么前端的 《HTTP 缓存机制一二》 文章中,Last-Modifed
和 Etag
的区别
- 某些服务器不能精确得到资源的最后修改时间,这样就无法通过最后修改时间判断资源是否更新。
- Last-modified 只能精确到秒。
- 一些资源的最后修改时间改变了,但是内容没改变,使用 Last-modified 看不出内容没有改变。
- Etag 的精度比 Last-modified 高,属于强验证,要求资源字节级别的一致,优先级高。如果服务器端有提供 ETag 的话,必须先对 ETag 进行 Conditional Request。
HTTPS
什么是 HTTPS?
HTTP + 加密 + 认证 + 完整性包含 = HTTPS
HTTPS 其实就是 HTTP 通信部分用 SSL(Secure Socket Layer) 和 TLS(Transport Layer Security) 协议代替
HTTPS 的握手阶段:
- client 发送 'Client Hello' 报文,开始 SSl 通信,报文包含 SSL 的指定版本、加密组件(Cipher Suite)列表
- server 进行 SSL 通信,回答 Servver Hello。包含 SSl 指定版本和加密组件,加密组件从接收到的客户端的加密组件筛选出来
- server 再发送 Certificate 报文,包含公开密钥证书
- server 最后发送 Server Hello Done 通知 client,SSL 握手协商部分结束
- client 以 Client Key Exchange 报文回应。报文包含通信加密使用的,被称为 Pre-master secret 的随机密码串(用于公开密钥的加密)
- client 继续发送 Change Cipher Spec 报文,提示服务器后续的报文采用 Pre-master secret 密钥加密
- client 发送 Finished 报文,包含连接至今全部报文的整体校验值
- server 发送 Change Cipher Spec 报文
- server 发送 Finished 报文
- 当 Finished 报文都交换完毕后,SSL 连接建立完成,通信会受到 SSL 保护
HTTPS 有什么用?
总结:HTTPS 就是在 HTTP 基础上多了一层 SSL,SSL 协议拥有加密的功能,再加 CA 的存在,可以建立一个信息安全通道,确认内容的真实性
因为 SSL 的加密功能时,信息在传递的时候是安全的,这样攻击者就无法获取到真实的内容,无法篡改内容
SSL 使用“公开密钥加密(Public-key cryptography)”进行加密处理(其实就是公钥秘钥)
加密、解密都使用同一个秘钥的就是:共享密钥加密(Common key crypto system),也称对称密钥加密
什么要使用公开密钥加密
如果使用共享密钥加密的话,如何把密钥安全地传给客户端?既然可以安全地传给客户端,还需要加密吗?
所以才要使用公开密钥加密。公钥是公开发布的,人人都可以获得,密钥只存在自己身上。比如客户端用公钥加密数据后,传输给服务器,服务器再用密钥去解密,这就达到安全地传输数据
使用公开密钥加密 + 共享密钥加密
共享密钥加密处理速度比公开密钥加密要快(为啥)
- 先使用公开密钥加密方式,交互共享密钥需要的密钥
- 后面的通信才使用共享密钥加密
如何证明获得的公钥是你想要的服务器的公钥?
使用数字证书认证机构(CA, Certificate Authority)和其他相关机关颁发的公开密钥证书
- 服务器的开发人员,会向 CA 提出公开密钥的申请
- CA 审核申请者后,会对申请的公钥做数字签名,然后分配公钥
- 将公钥放入公钥证书后绑定在一起
- 服务器会将这个公钥证书发送到客户端
- 客户端会对接收到的证书进行验证
客户端拿到服务器的公钥证书(存在浏览器)后,使用 CA 的公开密钥,向 CA 验证服务器的公钥证书,确保该公钥的真实性
SSL 的速度相比于 HTTP 会更慢
比 HTTP 通信,会多一次 SSL 通信,通信量会增加
服务器和客户端都要进行加密和解密的运算处理,增加更多的 CPU 资源消耗
而且购买 CA 证书,也需要费用
为什么要用 HTTPS?
使用 HTTPS 是代替 HTTP,HTTP 有一些不足的地方
通信使用明文,内容会被窃取
HTTP 是基于 TCP/IP 的,通信内容有可能被窥视(为啥 TCP 传输内容会被窥视?)
不验证通信方的身份,通信会被遭遇伪装
- HTTP 协议的请求和响应,不会对通信方进行确认(通信的对方,是否你要指定的主机)
- 任何人都可以对某个主机发起请求
无法证明报文的完整性,内容会被篡改
- 无法证明信息的完整性,内容可能会在传输中,被攻击者篡改
而 HTTPS 解决上面的问题
- 对通信通道进行加密,内容无法被窃取、篡改,保证完整性
- 服务器和客户端某一方拥有 CA 的话,即可判断通信方的真实存在
WebSocket
浏览器和服务器之间的双全工通信标准,通信双方都可以主动发送数据、接收数据
功能
- 通信双方都可以主动发送属性、接收数据
- 减少通信量,连接会一直保持着
- 连接成功后,通讯用的是 WebSocket 的数据帧(frame)
握手过程
- client 发起请求:Upgrade: websocket;Sec-WebSocket-key 记录握手过程的键值;Sec-WebSocket-Protocol 记录用的自协议
- server 响应:101 Switching Protocols;Sec-WebSocket-Accept 字段是由 Sec-WebSocket-Key 值生成的
- 建立连接成功
名词概念
数字签名(Digital Signature)
数据在浏览器和服务器之间传输时,有可能在传输过程中被冒充的盗贼把内容替换了,那么如何保证数据是真实服务器发送的而不被调包呢,同时如何保证传输的数据没有被人篡改呢,要解决这两个问题就必须用到数字签名。数字签名就是用于验证传输的内容是不是真实服务器发送的数据,发送的数据有没有被篡改过,它就干这两件事,是非对称加密的一种应用场景。不过他是反过来用私钥来加密,通过与之配对的公钥来解密。
第一步:服务端把报文经过Hash处理后生成摘要信息Digest,摘要信息使用私钥private-key加密之后就生成签名,服务器把签名连同报文一起发送给客户端。
第二步:客户端接收到数据后,把签名提取出来用public-key解密,如果能正常的解密出来Digest2,那么就能确认是对方发的。
第三步:客户端把报文Text提取出来做同样的Hash处理,得到的摘要信息Digest1,再与之前解密出来的Digist2对比,如果两者相等,就表示内容没有被篡改,否则内容就是被人改过了。因为只要文本内容哪怕有任何一点点改动都会Hash出一个完全不一样的摘要信息出来。