《JavaEE初阶》HTTP协议和HTTPS
文章目录
- 《JavaEE初阶》HTTP协议和HTTPS
- HTTP协议是应用层协议:
- 使用Fiddler抓取HTTP请求和响应:
- Fiddler的下载和基本使用:
- Fiddler的中间代理人身份:
- 其他抓包工具:
- 先简单认识HTTP请求与HTTP响应:
- HTTP请求:
- HTTP响应:
- HTTP请求详解:
- 首行:
- 认识URL
- HTTP中的方法:
- GET方法:
- POST方法:
- GET和POST的区别:
- 请求报头header
- 关于运营商劫持问题:
- 空行和正文:
- HTTP 响应详解:
- 1. 认识状态码:
- 2.认识响应报头header
- 构造HTTP请求:
- 使用from表单构造:
- 使用ajax构造:
- HTTPS:
- HTTPS的加密过程:
HTTP协议是应用层协议:
我们在之前就已经学到了客户端-服务器模型:
-
一问一答: 请求和响应是一一对应的
-
一问多答: 一个请求对应多个响应
-
多问一答: 多个请求对应一个响应
-
多问多答: 多个请求对应多个响应
HTTP协议为我们在应用层构建请求和响应.
使用Fiddler抓取HTTP请求和响应:
Fiddler的下载和基本使用:
下载:
Fiddler4 (telerik.com)
填写邮箱信息和勾选accept即可下载:
我们可以看到Fiddler打开后分为两部分:
我们由于在初学阶段,所以使用"Row"(原始) 来看HTTP的请求和响应数据.
对于HTTPS的抓取,我们需要在Fiddler 上做额外的一点工作:
在证书安装上一定要选"是",至于为什么安装证书,我们后面会讲解.
Fiddler的中间代理人身份:
像Fidder这样在中间传话的软件我们称之为"代理"
在我们的电脑上,可能会存在其他的代理软件,如果存在,那么可能会导致Fiddler无法正常工作.
同时由于Fiddler是中间代理人,所以需要接收数据和发送数据,这也带来了时间上的开销,会导致我们访问页面的效率下降(感受比较明显)
其他抓包工具:
除了Fiddler之外,市面上还有许多抓包工具,对于Fiddler来说,只能抓取HTTP和HTTPS(带加密版本的HTTP)协议,无法抓取TCP等其他协议.
而tcpdump或者wireshark则可以抓取TCP/UDP/IP协议,并且也可以抓取HTTP/HTTPS协议.
先简单认识HTTP请求与HTTP响应:
HTTP请求:
HTTP请求分为四个部分
-
首行:
其中包含了HTTP的方法(method),HTTP要请求的资源,HTTP的版本号.
-
请求报头headler
键值对的形式展示信息
-
空行:
作为请求报头headler 的结束标记,在报头中,键值对的数量有多少行我们是无法确定的,在遇到空行时,就认为该报头结束.
-
正文body:
并不是所有的HTTP请求都包含正文
我们可以看到这里正文的格式为JSON,并且我们这里抓取到的是HTTPS请求,所以正文部分的密码是加密后的,为我们保证了安全.
HTTP响应:
HTTP响应也分为四个部分:
-
首行:
使用空格将首行分为四个部分: 版本号 状态码 状态码描述.
-
响应报头headler
键值对的形式展示信息
-
空行:
作为响应报头header的结束标记
-
正文body:
直接抓取的HTTP响应,是看不见正文的信息的,只能看到一堆乱码.原因这是因为在网络传输中,响应数据一般都较大,而带宽资源是十分宝贵的,为了尽可能地减少带宽资源的消耗,HTTP响应对正文部分进行了压缩:
Content-Encoding: gzip 这个键值对表示正文部分是压缩状态.
Fiddler内置了解压缩功能:
对于HTTP响应的正文,形式多种多样:可以是HTML,可以是CSS,也可以是JSON等其他格式.
HTTP请求详解:
首行:
认识URL
URL 是唯一资源标识符
URL的详细规则由因特网标准RFC1738进行了约定:
规定链接
以一个具体的URL为例:
https://v.bitedu.vip/personInf/student?userId=10000&classId=100
我们可以看到许多信息都被隐藏了
这里是一个层层递进的过程:
首先明确URL的协议方案,找到服务器地址,通过DNS 解析后成为 IP 地址,在知道IP地址确定了主机地址后,我们还需要确认服务器在主机的哪一个端口号,在确认了端口号后就根据文件路径来访问具体的资源.
-
https: 协议方案名,这里一般是http或者https.
-
user:pass : 登陆信息. 现在的网站进行身份认证一般不再通过 URL 进行了. 一般都会省略
-
v.bitedu.vip : 服务器地址,此处是一个"域名", 会被DNS 系统解析成一个具体的IP地址
-
端口号: 这里的URL端口号被省略了,当端口号省略的时候, 浏览器会根据协议类型自动决定使用哪个端口. 例如 http 协议默认使用 80 端口, https 协议默认使用 443 端口.
-
/personInf/student : 带层次的文件路径.
-
userId=10000&classId=100 : 查询字符串(query string). 本质是一个键值对结构. 键值对之间使用 & 分隔. 键和值之间使用 = 分隔,对于字符串中的数据,我们是不需要看懂的,因为这是程序员自定义的.
-
片段标识: 此 URL 中省略了片段标识. 片段标识主要用于页面内跳转
在URL 中, 已经有一部分符号是作为特殊含义的, 如果在query string 中也存在这样的字符,那就会存在歧义,导致URL解析失败,所以为了解决这样的问题,URL引入了转义字符,例如%2B就是字符" + "的转义字符.
urlencode工具:UrlEncode编码/UrlDecode解码 - 站长工具 (chinaz.com)
HTTP中的方法:
HTTP的方法有很多种:
在学习中重点掌握GET和POST.
GET方法:
GET方法常用与获取资源,但这只是建议,并不是只能用来获取资源,GET方法也可以用来删除,新增,修改一个数据.
触发GET请求的场景:
-
直接在浏览器中输入URL,发生请求.
-
HTML的许多标签也可以触发GET请求.
-
使用from表单.
-
使用ajax.
GET的特点:
-
querystring 有时候有,有时候没有
-
body一般为空.
需要了解的其他知识:
-
对于GET请求的URL长度是没有限制的,这是HTTP的标准明确指出的"Hypertext Transfer Protocol --HTTP/1.1," does not specify any requirement for URL length"
在早期的浏览器中,由于空间有限,所以可能需要对URL的长度进行限制,但是在现代的浏览器中,空间已经十分充足了,所以不需要对URL进行长度限制.
-
在浏览器和服务器的交互中,浏览器是需要提供一些数据给服务器的,这个数据可以放在querystring,也可以放在body中.并且querystring只能是键值对的格式来组织数据,而body则可以是各种各样的数据格式.
POST方法:
POST方法一般用来请求资源,但是也可以用来获取,新增,修改,删除一个数据.
触发POST请求的场景:
-
登录
-
上传文件
POST特点:
-
URL通常没有querystring
-
通常有正文body
GET和POST的区别:
-
GET和POST并没有本质的区别,都是作为HTTP的方法,并且GET和POST都是可以相互替代的.只是在使用的习惯上有所不同.(下列都是习惯并建议这样使用GET和POST)
-
GET主要用来获取数据,而POST主要用来提交数据.
-
GET一般使用querystring来传递数据,而POST一般使用正文来组传递数据.
-
GET请求一般建议是实现为"幂等"的,而POST请求一般建议是为"不幂等"的.
‘幂等’: 即多次输入的内容一样,多次得到的结果也一样,这就被称之为"幂等".
-
GET请求一般是可以被缓存的/被放入收藏夹中,而POST请求一般是不可以被缓存的.
请求报头header
在请求报头中, 数据主要是以键值对的形式存在,这里我们认识几个常见并重要的:
-
HOST: 访问的主机或者服务器地址
-
Content-Length 和 Content-Type :
我们在之前就已经学习到TCP协议是以字节流来传递数据的,而基于TCP协议的应用层协议则需要明确数据与数据之间的边界,否则就会带来粘包问题.而HTTP协议就是以TCP协议为基础的应用层协议,所以我们需要明确HTTP请求的body要在什么地方结束.
Content-Length就是指明body的数据长度.
Content-Type就是指明body的数据格式.
在HTTP请求中,body的数据格式常见的为:
-
json
-
urlencoded : 格式也是键值对的形式
-
form-data
-
-
User-Agent (简称UA)
User-Agent 就是描述 你在一个什么样的设备上上网.
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36 Edg/112.0.1722.58
我们以上述这段User-Agent 来介绍:
-
Mozilla/5.0: 宣称浏览器为"Mozilla"浏览器.在很久之前想获得图文并茂的网页,就必须宣称自己是 Mozilla 浏览器。此事导致如今User-Agent里通常都带有Mozilla字样,出于对历史的尊重,大家都会默认填写该部分。
-
(Windows NT 10.0; Win64; x64) : 表示当前计算机的操作系统版本.
-
AppleWebKit/537.36 : 浏览器内核
-
Chrome/112.0.0.0 : 浏览器版本
在以前,由于浏览器的版本更新快,一些网站在老版本的浏览器只能查看文字,而在新版本中却能查看图片了,如果开发网站,就需要考虑新老用户,因此浏览器可以通过UA来通知服务器我是一个什么样版本的浏览器, 这样服务器就可以根据你浏览器的版本来分别处理,如果是老版本的浏览器,则返回一个简单的页面,如果是新版本的浏览器,则返回复杂的页面.
在如今 ,浏览器的版本已经相差不大,所以UA的作用也不大了, 现在主要用来区别PC端和移动端.
-
-
Referer:
表示这个网页是由之前的哪个网页跳转而来.
在header中 , Referer并不是一定存在的,只有当从其他的页面跳转过来的, 才会存在,如果是直接在浏览器输入URL跳转或者直接通过收藏夹进入网页,则一般不会有Referer.
关于运营商劫持问题:
在浏览器中,我们经常可以看到许多广告,而当我们点击进去,A浏览器服务商就要向广告主收取广告费, 并且是通过Referer来统计我们点击的次数,同时广告主也可以知晓网站中的请求是来自于A浏览器服务商的.
但是Referer是可以被篡改的, 浏览器服务商是没有这个能力的,有这个能力的只有网络运营商,由于所有的操作都需要经过网络运营商的网络设备,所以他们可以解析请求的内容并进行篡改,如果将referer进行了篡改,那么这一部分广告费就会属于网络运营商.对浏览器服务商的利益造成损害.
在技术上是可以做到反制的:
使用HTTPS,我们已经知道HTTPS是具有加密功能的,运营商劫持之后,需要进行破解,提高了难度,并且破解后进行了篡改,浏览器也可以很轻松的识别是否被篡改并发出警告.
-
Cookie:
Cookie: 是浏览器在本地存储数据的一种方式.
Cookie的数据从服务器写入,相当于登录成功一次后,服务器认可你的身份,并且向你写入cookie数据,下一次登录时就不需要进行身份验证.
cookie的数据传如服务器时,相当于会带着身份标识,这样服务器看见你的身份标识就不需要验证身份了.
我们在登录完网页后,我们可以发现下一次我们可能就不需要登录了,浏览器会为我们保存下我们的个人信息,这个功能就是Cookie来实现的.
浏览器为了保证用户的安全,是对访问进行了十分严格的限制的,浏览器并不能访问本地磁盘,但是我们需要存储信息,又不得不访问本地磁盘,为了能存储信息, 浏览器规定:
-
可以使用磁盘,但是只能使用十分小的一部分,
-
页面代码不能任意访问磁盘和存储数据,只能存储简单的键值对
我们点击这个锁头,就可以看见cookie信息,每一个域名(网站)都有自己的一组cookie,cookie中的内容是程序员自定义的,我们无需看懂.
在web开发中, session和cookie一般是搭配使用的,我们可以简单理解为: seesion是银行的保险柜,其中有很多钱, 而cookie是银行卡,可以找到对应的保险柜.
但是单独的cookie也是可以使用的,并不一定要存储身份信息,也可以存储程序员想要存储的其他信息
-
空行和正文:
这里的内容并不是很多,在上文简单认识HTTP请求中已经讲的差不多,就不再写了.
HTTP 响应详解:
1. 认识状态码:
-
200: 表示成功,没有出错
-
404 : 表示"Not Found" 要访问的资源没找到.
-
403: 表示"访问被拒绝" 即:访问的资源存在,
-
405: 表示请求的方法不支持,(例如,使用DELETE方法访问,但是服务器不支持DELETE)
-
500: 表示服务器内部错误.
-
504: 表示超时,即请求发过去之后,没有收到响应,当浏览器等待的时间到了,就会触发.
-
302/301 : 表示重定向.
301 永久重定向
302 要求客户端临时重定向
303 临时重定向,对应当前请求的响应可以在另一个URI上被找到,当响应于POST(或PUT / DELETE)接收到响应时,客户端应该假定服务器已经收到数据,并且应该使用单独的GET消息发出重定向
307 临时重定向,在这种情况下,请求应该与另一个URI重复,但后续的请求应仍使用原始的URI
2.认识响应报头header
这里的响应报头header中的大部分键值对与请求是一样的,有区别的主要是Content-Type.
响应报头的Content-Type的值比较丰富
-
text/html: 即body的数据格式是HTML
-
text/css : 即body的数据格式是CSS
-
application/javascript: body的数据格式是JavaScript
-
application/json : body 数据格式是 JSON
构造HTTP请求:
使用from表单构造:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<form action="www.baidu.com" method="post">
<br>输入账号
<input type="text" name="username">
<br>输入密码
<input type="password" name="password">
<input type="submit" name="提交">
</form>
</body>
</html>
from的效果就是构造HTTP请求,
action 描述了 HTTP请求URL 的地址/端口/路径.
method描述了HTTP请求的方法.
搭配一些input标签即可构造数据的HTTP请求.
使用ajax构造:
Ajax 的全称是asynchronous javascript and xml ,Ajax 是已有技术的组合,主要用来实现客户端与服务器端的异步通信效果,实现页面的局部刷新。
ajax是组织数据的一种格式,也是以成对的标签存在.
ajax是浏览器给JS提供的一种和服务器交互数据的机制,其中浏览器给用户提供的原生API:XMLHttpRequest 使用起来不方便,可能受到更多出于安全等原因的限制。所以我们采用另一种方式jquery.
jquery对ajax就进行了封装:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script src="jquery.min.js"></script>
<script>
$.ajax({
type:'GET',
url: 'http://www.baidu.com',
//data: 正文的部分,可有可没有
success: function(body){
//参数body是HTTP响应的正文部分
//这个 函数是一个回调函数,并不会立即执行,只有在浏览器收到服务器的响应后才执行.
}
})
</script>
</body>
</html>
-
type: 指明HTTP请求的方法,这里方法不限制于只能是GET和POST,也可以是HTTP的其他方法.比from使用更全面.
-
url:表示当前HTTP请求将访问的资源地址。
-
data: 表示HTTP请求的正文数据
-
success: function(body) :是一个回调函数,并不会立即执行,只有在浏览器收到服务器的响应后才执行.
如果我们直接运行上面的代码,我们会发现访问失败,并且在控制台上可以看见报错信息:
这个报错是ajax典型的问题:"跨域"问题.
当前我们的ajax是一个本地HTML文件,而ajax所请求的是百度的服务器.
而浏览器是禁止我们进行跨域访问的,如果需要跨域访问,需要得到服务器的支持.
当然,百度服务器是不会同意个人的文件去访问服务器的.
但是在我们进行开发时,我们可以使自己的服务器去同意浏览器来访问自己的服务器.
HTTPS:
HTTPS与HTTP的区别就在于HTTPS多了个"加密层".
HTTP是明文传输的,这也意味着会被其他网络运营商和黑客锁截取数据并且篡改,而HTTPS的出现就是为了避免数据被窃取修改.
明文: 为HTTPS请求和响应所要发送和接收的真实数据,即没有进行加密的数据
密文: 为HTTPS请求和响应所要发送和接受的加密后的数据.
密钥: 用于解析密文和明文的钥匙.
-
明文通过密钥变成密文,就是"加密".
-
密文通过密钥变成明文,就是"解密".
如果加密和解密的过程中使用的是同一把密钥,那么称之为"对称加密".
如果加密和解密的过程中使用的是不同的密钥,那么称之为"非对称加密".
HTTPS的加密过程:
在上述过程中,可能不止有一个客户端,当服务器与多个客户端进行交互时,我们应该采用对称加密还是非对称加密,结果显而易见,如果我们采用对称加密,那么黑客是不是只要伪装成一个客户端,那么就可以轻松的获取到密钥了,进而对数据进行解密.那么我们如果希望将对称密钥进行对称加密,那么就会陷入一个死循环中,黑客无论如何都能获取到
故而我们是需要采用非对称加密来加密我们的对称密钥.
非对称加密的两把密钥:
用来加密的两把钥匙是一对有关联的数字(根据数论,两个很大的素数可以很容易地得到乘积,但是根据乘积很难得到原来的两个素数)
将这对密钥,一部作为公钥,一部作为私钥.
我们可以使用公钥进行加密,私钥来解密,也可以相反使用.
以下列例子作为非对称加密的流程.
-
客户端和服务器生成了我们的对称密钥: 88888
-
客户端利用公钥对对称密钥88888进行加密,发送给服务器.
-
由于中间的设备没有私钥,只有公钥,所以无法解析密钥是啥.
-
服务器通过私钥进行解密,解密完成后的响应再使用公钥进行加密,返回给客户端.
-
在后续服务器和客户端只需要进行对称加密即可,于该密钥只有客户端和服务器两个主机知道,其他主机/设备不知道密钥即使截获数据也没有意义.
由于对称加密的效率比非对称加密高很多, 因此只是在开始阶段协商密钥的时候使用非对称加密,后续的传输仍然使用对称加密.
但是上面并不是无懈可击的,黑客可以采用"中间人攻击"破解:
我们发现,当黑客自己使用一对公钥和私钥时,是完完全全可以获取我们的对称密钥的.
那么如何破解中间人攻击呢? 只要客户端能够准确地识别公钥是否来自真实的服务器即可.
HTTPS引入了一个"证书机制".
通过引入证书和认证机构, 黑客就无法通过自己生成公钥和私钥来破解出对称密钥, 证书中包含了公钥和其他信息,如果黑客篡改了证书中的内容,那么浏览器在认证机构的帮助下依然可以轻松的破解黑客的手段,(只要发现证书被篡改,就会发出警告来提示用户)