HTTP和HTTPS
- HTTP协议
-
- HTTP请求
-
- 1.组成
- 2.方法
- 3.header里面的一些键值对
- 4.TCP粘包问题的补充
- HTTP响应
-
- 1.组成
- 2.几大类:
- 3.HTTP请求构造
- HTTPS协议
-
- 1.生成密钥
- 2.公信机构
HTTP协议
HTTP处于TCP/IP五层协议栈的应用层,HTTP协议在传输层呢个是基于TCP的(详细的说,HTTP/1 HTTP/2是基于TCP,最新版本HTTP/3是基于UDP,但是当下互联网绝大部分都是HTTP/1.1)
应用层协议则是站在程序应用的角度,要对传输的数据进行具体的使用。
协议格式:数据具体是怎么组织的。HTTP请求
HTTP是一个文本格式的协议(不需要去理解具体的二进制位,而只是理解文本的格式即可)
文章图片
文章图片
1.组成
请求分成4各部分
- 请求行(首行),包含三个部分 1)HTTP的方法,方法大概描述了这个请求想干啥,GET的意思就是想从服务器获取到某个东西 2)URL,描述了要访问的网络上的资源具体是在哪 3)版本,HTTP/1.1表示当前使用的HTTP的版本是1.1(1.1是当下最主流的版本,还可能是1.0/2/3)
- 请求头(header),包含了很多行,每一行都是一个键值对,键和值之间用:,空格来分割。这里的键值对个数是不固定的(有可能多,也有可能会少),不用的键和值标识的含义也有不同。
- 空行 相当于请求头的结束标记,类似于 链表的 null
- 请求正文(body) 可选的不一定有
1)URL
网络上唯一资源的地址符,既要明确主机是谁,又要明确是主机上的那个资源
文章图片
- 协议方案名:描述了当前这个URL是给那个协议来使用的,http://给HTTP用的,https://给HTTPS用的,jdbc:mysql://给jdbc:mysql使用的
- 服务器地址:当前要访问的主机是啥,这里可以是一个IP地址也可以是域名
- 服务器端口号:当前要访问的主机上的那个应用程序(端口号大部分情况下是省略的),省略的时候不是说没有,而是说浏览器会自动赋予一个默认值。对于HTTP开头的URL就会使用80端口作为默认值,对于HTTPS开头的URL就会使用443端口作为默认值。
- 带层次的文件路径:描述了电脑前要访问的服务器的资源是啥。虽然请求中的URL写的是一个文件路径,但是不一定是服务器就真的存在一个对应的文件,这个文件可能是一个真实的在磁盘上存在的文件,也可能是虚拟的有服务器代码构造的动态数据。
- 查询字符串:本质上是浏览器/服务器,给服务器传递自定义的信息,相当于对获取到的资源提出了进一步的要求,查询字符串的内容本质上也是键值对结构,完全是程序员自己定义的,查询字符串和路径之间使用?来分割。
- 片段标识符:描述了要访问当前html页面的中的具体的字部分,能够控制浏览器滚动到相关位置。
当query string中如果包含了特殊字符就需要对特殊字符进行转义,这个转义的过程就叫做url encode。反之把转以后的内容还原过来就叫做url decode。url里面有很多特殊含义的符号的,/:?=…这些符号都是在url中具有特定含义的,万一query string里面包含这类特殊的符号就可能导致URL被解析失败。
例如字符+的ascii的16进制表示2B。URLencode的规则就是要把转义的内容的ascii码值用16进制表示,同时再加上%,每个字节都分别这样处理。在实际开发过程中不仅仅是标点符号,还有中文字符,如果不专一就可能会带来问题。
2.方法
文章图片
最常用的GET,POST。HTTP引入这些方法初衷是为了表示不同的语义,但是随着时间的推移使用就走形,现在大家写代码都是不区分。
经典面试题:谈谈GET和POST区别
GET和POST没有本质区别,具体来说GET使用的场景也能替换成POST,POST使用的场景也能替换成POST。但是细节上还是有一些区别的。
- 语义上的区别,GET通常用来取数据,POST通常用来上传数据。现状是GET也经常来上传数据,POST也经常用来获取数据。
- 通常情况下,GET是没有body,GET通过query string向服务器传递数据。通常请款下,POST是有body的,POST通过body向服务器传递数据,但是POST没有query string。
但实际上如果想让GET有body,或者让POST有query string完全是可以的 - GET请求一般是幂等的,POST请求一般是不幂等的。 幂等:每次相同的输入,得到的输出结果是确定的。不幂等:每次相同的输入,等到的输出结果是不确定的
- GET可以被缓存,POST不能被缓存。如果是幂等的,记住结果节省了下次访问的开销时间。如果不是幂等的就不应该记住。
- Content-Length:表示body中的数据长度
- Content-Type:表示请求的body中的数据格式
一般POST都是带body,登录一般都是基于POST来实现的。原因是登录肯定就要给服务器传递用户名和密码,如果是GET,用户名和密码习惯就会放到URL的query string中来传递(此时浏览器的地址栏里的信息的路径就可能变得很长一串,这时候用户体验具很不好)
- application/json:数据为json格式,body格式形如:{“username”:“xxx”,“password”:“xxxxxxx”}
User-Agent:表示对那个钱用户是用什么东西来上网。操作系统信息+浏览信息
文章图片
- Cookie:浏览器给页面提供一种能够持久化存储数据的机制,持久化指的是数据不会因为程序重启或者主机重启而丢失(写到磁盘里)。cookie最重要的应用场景就是存储会话id,进一步的让访问服务器的后续页面的时候,能够带上这个id从而让服务器能够知道当前的用户信息(服务器上保存用户信息这样的机制就成为Session会话)
1.先按照域名来组织,针对每个域名分别分配一个小房间。
2.一个小房间里面有会按照键值对的方式来组织数据。
- Referer:表示了当前这个页面是从哪个页面跳转过来的(Referer不是一定有的,如果是从浏览器地址栏直接输入地址,或者直接点收藏夹,这个时候是没有referer)
解决TCP粘包问题的方法,合理设计应用层协议来明确保合宝之间的边界。1.使用分隔符 2.使用长度
- 情况1:如果当前有若干个GET请求,到了TCP接收缓冲区中,应用程序读取请求的时候就以空行作为分隔符。
- 情况2::如果当前是有若干POST请求到了TCP缓冲区,这个时候空行后面还有body,当应用程序读到空行之后就需要按照Content-Length标明长度,继续读若干长度的数据。
对于URL来说,里面的结构看起来比较复杂,其实最重要的和开发关系最密切的就是四个部分:
- ip地址/域名
- 端口号(经常是小透明)
- 带层次结构的路径
- query string 查询字符串
【http|HTTP和HTTPS详解】
文章图片
文章图片
- .首行:包含了三个部分
1)版本号 HTTP/1.1
2)200状态码,描述了这个响应,是一个成功的还是失败的,以及不同的状态码描述了失败的原因 3)OK状态码的描述,通过一个或一组简单的单词,来描述当前状态码的含义 - 响应头(header)
也是键值对结构,每一个键值对占一行,每一个键和值之间使用:来分割,响应头中的键值对的键值个数也是不确定的,不同的键值对表示不同的含义。 - 空行 表示响应头的结束标记
- 响应正文(body)
服务器返回给客户的具体数据,这里的东西肯呢个有各种不同的格式,其中最常见的格式,html。还有其他css,js,json。 - 状态码
1)200 OK 浏览器很顺利的就获取到想要的内容了
2)404 Not Found 要访问的资源不存在
3)403 Forbidden 虽然资源有但是没有权限访问
4)405 Method Not Allowed 方法不允许,例如尝试使用GET来访问服务器,但是服务器只支持POST,于是就会返回405
5)500 Internal Server Error 服务器自己出问题了,意味着出现了bug
6)504 Gateway Timeout 服务器太繁忙了
7)302 Move temporarily 重定向,在重定向响应中一般都是需要Location属性的,Location就描述了接下来要跳转到哪里,常用于登录过程中。
2开头,都属于成功3.HTTP请求构造
3开头,都属于重定向
4开头,都属于客户端出现错误了
5开头,都属于服务器出现问题了
(客户端构造HTTP请求,最常见的HTTP客户端就浏览器)
1.基于HTML/JS
1)基于form表单
首先form标签
文章图片
其次搭配标签
文章图片
最后提交按钮来触发HTTP请求
文章图片
2)基于ajax
form表单这种方式是一种更加原始的构造方式,使用form一定会涉及到“页面跳转”。随着页面越来越复杂,为了使页面不去整个加载,而是加载一下部分就可以使用ajax。
通过js代码来构造出HTTP请求,在通过js代码来处理这里的响应,并且把得到的一些数据个更行到页面上。
同步和异步之间的区别:
1)同步等待结果是调用者主动关注,
同步阻塞等待:等的过程中不干别的
同步费阻塞等待:等的时候可以干别的事情,(每隔一段时间就去查询一下结果)
2)异步等待结果是是被调用者通知
ajax就是属于异步等待的方式来进行的,首先藕造出一个HTTP请求发送给服务器。但是浏览器不确定服务器什么时候才有响应,于是先不管了,浏览器里面就继续执行其他代码。等到服务器的响应回来之后再由浏览器通知对应js代码,以毁掉函数的方式来处理响应。原生的写法非常麻烦也比较抽象,可以使用基于jQuery中的ajax来演示相关代码。引入jquery
1.现在搜索引擎搜索jquery.cdn查询词
2.在结果中找到一个合适的cdn的url
3.打开对应的url,加载出的jquery本体
4.复制粘贴内容到本地文件
文章图片
文章图片
注意:ajax不支持跨域访问
3)基于socket
HTTPS协议 HTTPS在HTTP的基础上引入了一个加密层。原因是为了解决运营商劫持,之前的HTTP是明文传输,传输的数据是容易被获取的也是容易被篡改的,引入HTTPS对数据加密做到保护数据安全。
明文:要传输的原始信息加密层(SSL(旧的叫法)/TLS(新的叫法))
密文:整个奏折即使被别人获取到了也看不出来什么毛病
密钥:通过密钥来吧明文转成密文,或者是密文还原成明文。
1.生成密钥 加密操作的方式:
- 对称加密:使用同一个密钥即可以加密也可以解密
- 非对称加密,有两个密钥,公钥就是人人能够获取到的,私钥就是自己才知道的。使用公钥来加密,使用私钥来解密。
文章图片
服务器自己持有私钥,客户端持有公钥,黑客可以拿到公钥但是拿不到私钥。客户端生成了对称密钥就可以用刚才的公钥对对称密钥进行加密,如果黑客拿到了这个密文,那么此时由于黑客没有私钥是不能进行解密的,也就不知道对称密钥是啥。
2.公信机构 上述过程看起来很完美了,但是还存在一个非常大的漏洞,就是要把自己的公钥返回给客户端,在这个操作过程中就可能会涉及到一个非常经典的“中间人攻击”。
文章图片
文章图片
中间人攻击的关键就是黑客自己也生成一对公钥私钥,拦截到服务器给客户端返回的公钥,用自己生成的共要替换它,和柯蓝接到对称密文之后,由于这个密文是使用public key2来进行加密的,因此黑客就可以使用private key2进行解密,黑客就拿到了对称密钥888888,紧接着黑客为了隐藏自己把888888在使用之前从服务器拿到的public key进行加密得到了另一个密文。
如何解决?
引入一个第三方的公信机构来证明这个公钥是一个合法公钥。
文章图片
每次都访问公信机构是不是太麻烦了?
客户端自身就会包含一些公信机构的信息(内置在操作系统里),不需要通过服务器网络请求直接进行认证。
推荐阅读
- 面试笔试题|Https的加密原理是什么()
- C语言|UDP网络编程
- 笔记|计算机网络-传输层
- VC++|分享体积小巧,功能强大的网络嗅探和分析工具SnifferView 版本-1.0.0.25
- 10款功能强大的网络嗅探工具应用分析
- DNS这位“翻译官”是如何转换域名和IP地址的()
- http|《彩虹屁》快夸夸我!彩虹屁生成器