响应报文格式
响应报文格式由首行,响应头(header),空行,正文(body) 组成
响应报文首行包括1.版本号 如HTTP/1.1
2.状态码(如200) 描述了请求的结果
3.状态码描述(如OK)
首行------状态码
这里主要介绍一下响应报文里面的 状态码 和状态码描述,它们描述了这次HTTP请求是否成功以及失败的原因
信息类(1xx)这里的状态码大体意思就是表示请求已被接收,但需要客户端继续发送请求,很少用到这里的状态码。
成功类(2xx)
这里的状态码表示请求已成功处理,200 ok 是我们最常见的一个状态码,表示访问成功.
重定向类(3xx)
3xx 表示 重定向。重定向指的是请求中访问的是 A 这样的地址,响应返回了一个重定向报文,告诉你应该要访问 B 地址
很多时候,页面跳转,就可以通过重定向来实现,还有的时候,某个网站服务器迁移了. IP/域名变了,就可以给旧的地址挂一个重定向响应,访问旧地址的用户就自动跳转到新的地址
这里有两个常见的状态码
301 Moved Permanently(永久重定向)
- 含义:请求的资源已永久移动到新的位置。
302 Found(临时重定向)
- 含义:请求的资源临时移动到新的位置。
客户端错误类(4xx)
• 表示客户端的请求有误,服务器无法处理。
• 常见状态码:
• 400 Bad Request:请求格式错误。
• 401 Unauthorized:请求需要用户认证。
• 403 Forbidden:服务器拒绝请求(权限不足)。
• 404 Not Found:请求的资源不存在。
• 405 Method Not Allowed:请求方法不被允许(如 GET 请求不允许使用 POST)。
服务器错误类(5xx)
表示服务器在处理请求时发生了错误。
常见状态码:
500 Internal Server Error:服务器内部错误。
501 Not Implemented:服务器不支持请求的方法。(get或者post)
503 Service Unavailable:服务器暂时不可用(如过载或维护)。
响应头
响应头 (header)跟请求头结构一样,键值对内容跟请求头差别没有很大,以下是响应头键值对的主要内容:
唯一要说的点就是content-typent,由于这是响应报文,响应报文里绝对会有body内容,body里的内容可能比较长, 会有多种格式,如HTML, CSS, JS, JSON, XML, 图片, 字体, 视频, 音频等,比请求报文里的body种类多好多。
回顾一下
请求报文中body内部的数据类型,有以下三种数据类型
1.json,具体类型为 application/json
2.form表单的格式,具体类型为application/x-www-form-urlencoded:form
3.form-data 的格式,multipart/form-data: form
除此以外,空行依旧是响应头的结束标志,body我们响应头该提的都提了,这里也不多说了
如何构造HTTP请求
在讲完HTTP协议的报文结构后,我们接下来就要去了解下面两个问题
如何让客户端构造一个 HTTP 请求?
如何让服务器处理一个 HTTP 请求 ?
处理请求涉及到Servlet/Spring ,它非常重要,要讲清楚如何处理要花非常多的时间,所以这里我们就先只讲如何构造一个HTTP请求。
首先我们能直接在浏览器 地址栏 输入 url, 此时构造了一个 GET 请求, 又或者在htm| 中, 一些特殊的 htm| 标签, 可能会构造 GET 请求,比如像 img, a, link, script。如果通过代码的话,我们能通过form或者是ajax的方式去构造,这里都是前端代码,就不说了
除此以外还有一种代码的方式,通过Java scoket构造HTTP请求,所谓的 "发送 HTTP 请求", 本质上就是按照 HTTP 的格式往 TCP Socket 中写入一个字符串. 所谓的 "接受 HTTP 响应", 本质上就是从 TCP Socket 中读取一个字符串, 再按照 HTTP 的格式来解析. 我们基于 Socket 的知识, 完全可以构造出一个简单的 HTTP 客户端程序, 用来发送各种类型的 HTTP 请求。
**除了这些以外,我们还能通过第三方软件去快捷生成HTTP请求,这是最方便的,**这里我们推荐用postman软件
HTTPS协议
当前网络上,主要都是 HTTPS 了,很少能见到 HTTP
实际上 HTTPS 也是基于 HTTP,前面讲过的 HTTP 的各个方面的内容, 对于 HTTPS 同样适用,报文结构都是一样的。只不过 HTTPS 在 HTTP 的基础之上, 引入了"加密"机制.
引入 HTTPS 防止你的数据被黑客篡改(尤其是反针对 运营商劫持) ---运营商可能修改广告访问次数来和企业合作获利
加密机制是什么?
明文:要传输的原始数据密文:经过加密之后得到的数据
密钥:进行加密和解密过程的重要道具
加密就是把明文(要传输的信息)进行一系列变换,生成密文.解密就是把密文再进行一系列变换,还原成明文.
在这个加密和解密的过程中,往往需要一些数据才能进行转换,这样的数据称为密钥
既然要保证数据安全, 就需要进行 "加密".网络传输中不再直接传输明文了, 而是加密之后的 "密文".
加密的方式有很多, 但是整体可以分成两大类: 对称加密 和 非对称加密
对称加密其实就是通过同一个 "密钥" , 把明文加密成密文, 并且也能把密文解密成明文。
非对称加密要用到两个密钥, 一个叫做 "公钥", 一个叫做 "私钥". (私钥是自己必须严格保密的钥匙,公钥是公开发布给大家的钥匙)
- 通过公钥对明文加密, 变成密文
- 通过私钥对密文解密, 变成明文
也可以反着用
- 通过私钥对明文加密, 变成密文
- 通过公钥对密文解密, 变成明文
公钥和私钥是配对的. 它最大的缺点就是运算速度非常慢,比对称加密要慢很多.但安全性高
HTTPS保证自己的安全性过程
在讲完上述加密概念后,我们就能去讲述HTTP如何保证自己的安全性了

但事情没这么简单. 要想进行对称加密,就需要客户端和服务器都具有同一个对称密钥,服务器同一时刻其实是给很多客户端提供服务的. 这么多客户端, 每个人用的秘钥都必须是不同的(如果是相同那密钥就太容易扩散了, 黑客就也能拿到了). 因此服务器就需要维护每个客户端和每个密钥之间的关联关系,这是个极其累的事,如果还要服务器再生成密钥的话就太负载了。
这个时候比较理想的做法, 让每个客户端生成一个密钥,在客户端和服务器建立连接的时候, 传输给服务器让服务器也有。
但是如果直接把密钥明文传输, 那么黑客也就能获得密钥了,此时后续的加密操作就形同虚设了。因此密钥的传输也必须加密传输!
但是要想对密钥进行对称加密, 就仍然需要先协商确定一个 "密钥的密钥". 这就无限套娃了. 此时密钥的传输再用对称加密就行不通了,我们就选择用非对称加密进行密钥的传输。
引入非对称加密
服务器会自己生成一对公钥和私钥,并且把自己生成的公钥传输给客户端,私钥还是自己来持有。
接下来客户端会对自己的对称密钥(每个客户端生成自己的,客户端之间不知道别人的对称密钥是啥),比如上图的这个客户端生成的对称密钥时六个8,此时这个六个8不会明文传输,通过刚才从服务器拿到的公钥,来针对对称密钥进行加密,再把对称密钥的密文传输给服务器,这样服务器就知道了对称密钥是什么。
此时黑客拿到对称密钥的数据之后,是无法解密的,使用公钥加密,就得使用对应的私钥来进行解密,黑客能轻松拿到公钥,而拿不到私钥,这样是解密不了数据的。
我们要注意一个服务器只会生成一对公钥和私钥(意味着所有和它连接的客户端都是用同一套公钥进行加密)
既然已经引入了非对称加密,为啥还需要引入对称加密呢?直接使用非对称加密,来完成所有业务数据的加密传输即可
这是因为进行非对称加密/解密,运算成本是比较高的.运算速度也是比较低的,对称加密运算成本低, 速度快.使用非对称加密kkkk,只是用来进行这种关键环节(传输密钥)(一次性的工作,体积也不大),成本就比较可控后续要传输大量的业务数据,都使用效率更高的对称加密,比较友好的做法.
如果业务数据都使用非对称加密,整体的传输效率就会大打折扣了.
注意:上述流程看起来很美好,但是黑客依然能获取到原始数据,通过中间人攻击去获取。中间人攻击问题
下面我们说下中间人攻击的流程:
客户端访问服务器(黑客冒充的),请求公钥,服务器就会生成一对公钥和私钥(提前生成好的),在此我们称为pub,pri,然后把公钥(pub)返回给黑客
这时就到了关键环节:黑客可以自己生成出一对公钥(pub2)和私钥(pri2),黑客就会把自己的公钥(pub2)返回给客户端,客户端就无法区分出当前的pub2是不是服务器最开始返回的公钥,是不是被中间人掉包了的公钥,客户端就只能选择相信,客户端就会拿着pub2针对对称密钥进行加密,并且发送给服务器(黑客),此时黑客就会拿着pir2针对刚才收到的pub2加密的数据进行解密,从而拿到这里的对称密钥,黑客继续把拿到的对称密钥,使用服务器的公钥pub再次加密发送给服务器,服务器就会使用自己的私钥进行解密,此处肯定会解密成功,拿到对称密钥,接下里意味着客户端和服务器就会继续使用这个对称密钥来完成后续的业务数据加密,此时对称密钥已经泄露出去了
上述过程,黑客面对服务器的时候,扮演客户端的角色,面对客户端的时候,扮演服务器的角色,那么客户端和服务器都不知道黑客的存在,这样就很神秘的泄露出去了。
引入证书
上面讲到,客户端无法区分拿到的公钥是否为服务器返回的公钥,还是说其他人伪造的公钥。那么客户端如果能做出区分,当前的公钥是否为服务器返回的公钥,中间人攻击就不攻自破了。
为了解决该问题,我们引入第三方的可以被大家都信任的"公证机构",公证机构说这个公钥是正确的,不是被伪造的,我们就是可以信任的。所有的服务器在上线自己的网站的时候,都要先去第三方公证机构申请一个证书(此处的证书并不是纸质的,而是数字证书,可理解为一串字符串数据),这个证书包含:发证机构,有效期,服务器的公钥,证书持有者,持有者网站,主域名,数字签名......这个数字签名可理解为一个加密之后的校验和,校验和是基于CRC/MD5等方式,把证书的其他内容的每个字节都带入计算一遍,最终得到的一串字符串,然后针对校验和进行非对称加密的方式进行加密,那么是谁的私钥进行加密的呢?
公证机构自己会生成一对公钥和私钥(和服务器的公钥私钥不一样),公证机构会自己持有私钥,而每个电脑的操作系统都会内置公证机构的公钥,公证机构会拿自己的私钥针对证书数据的校验和进行加密,得到数字签名。
在申请了证书后,我们就不再发送公钥了,而是直接发送证书(证书里面包含公钥)
客户端拿到了证书,也就拿到了证书中的公钥,客户端就需要验证这个公钥是否是服务器最初的公钥(是否是被黑客篡改了)
这个过程就称为证书的校验,如何进行校验?
此时,客户端拿到了数字签名,就可以通过操作系统内置的公证机构的公钥进行解密了,得到最初的校验和,客户端再重新计算一遍这里的校验和,和解密出来的校验和进行对比,如果校验和一致,就可以认为证书没有被篡改过,公钥就是可信的
在上述机制下,黑客就无法对证书内容进行篡改了,即使篡改,也很容易被发现.
当黑客收到证书之后,如果直接修改里面的公钥,替换成自己的,客户端在进行证书校验的时候,就会发现校验和不一致了,客户端就可以认为是篡改过了.(客户端这边往往就会弹出一些对话框来警告用户,存在安全风险)
那么黑客在替换公钥时,同时替换掉数字签名是否可以呢?在算出自己的校验和时,针对校验和加密,需要使用公证机构的私钥才能进行.黑客没有这个私钥.如果黑客拿自己的私钥加密,客户端也就无法使用公证机构的公钥解密了公证机构的公钥是客户端系统自带的,黑客也无法替换(如果不对校验和进行加密,黑客还真可能得逞)
结合上述过程,证书就是可信的,通过了校验,就说明公钥就是服务器原始的公钥了,完美解决了中间人攻击问题
所以https是通过以下三点相结合保证 https 的安全性:
1.对称加密,加密业务数据2.非对称加密,加密对称密钥
3.使用证书,校验服务器的公钥这是一道经典的面试题,我们要深刻的理解它。