HTTP协议
HTTP是一个非常广泛的应用层协议
应用层协议,经常是需要进行"自定义协议"的,但是,很多时候也不一定非得从零设定开始,也可以基于一些大佬们设计好的协议,在这个基础上进行定制,HTTP之所以应用非常广,主要是因为HTTP可定制性非常强,以HTTP为蓝本,在这个基础之上捎带着你想要传输的数据,这个时候就很容易完成一个自定义协议了
啥时候会用到HTTP协议呢?
只要你在上网,就在使用,比如
1.浏览一个网页
2.手机app从网络上加载一份数据
3.wx小程序,支付宝小程序
4.打开游戏,游戏的一些界面
HTTP应用的范围非常广,因此说HTTP是应用层最广泛的协议,不管你是前端还是后端,HTTP是一个程序员必须要掌握的协议
HTTP协议的工作过程
HTTP是一问一答形式的
一个请求对应一个响应
HTTP是一个应用层协议,HTTP请求发送出去之后,就需要从应用层到物理层,层层封装,接收方接收到数据之后,再从物理层到应用层,层层分用,最后才能够完成传输
HTTP的报文协议格式
学习HTTP协议,最主要的还是学习HTTP的报文协议格式
要想认识报文格式,需要借助一些外部的工具,来吧HTTP协议给显示出来,这个工具就是抓包工具,就是把数据包给他抓出来,然后显示这个包的报文格式,抓包工具相当于一个代理,借助这样的代理,就可以看到网络上传输的具体数据
抓包工具有很多
chrome(内置了抓包工具)
wireshark(学校计算机网络课,经常会涉及到这个),功能全面,使用复杂,ip,tcp,udp,http都能抓
这里使用的是fiddler,专注于http,使用简单(实际工作中抓包,fiddler也够用了)
Fiddler使用
浏览器访问 sogou.com 时, 就会把 HTTP 请求先发给Fiddler,Fiddler 再把请求转发给 sogou 的服务器. 当 sogou 服务器返回数据时,Fiddler 拿到返回数据, 再把数据交给浏览器. 因此 Fiddler 对于浏览器和 sogou 服务器之间交互的数据细节, 都是非常清楚的.
请求
响应
也是点击Raw
正文也可以叫body
借助上述抓包工具,就看到了http协议请求和响应的具体内容了
请求首行
方法
HTTP有很多方法
但是最常用的是GET和POST
POST:往服务器提交个啥东西
日常开发中绝大部分用的都是GET
举个例子:
东晋谢灵运说才高八斗,意思是天下文采分十斗,曹子建独占八斗,他自己占一斗,天下文人占一斗
如果天下的http请求分十斗,GET独占八斗,POST占一斗,剩下的占一斗
那么啥时候能看到POST呢?
1.登陆的时候
2.上传文件的时候
POST请求的正文(body)一般不为空
GET请求的正文(body)一般为空
下面看一个登录的http请求
GET和POST虽然表示的是不同语义,但是实际上,也并非需要严格遵守,http方法的语义只是一种建议,程序员实际使用的时候,也不一定必须要遵守,毕竟你自己写的代码你自己负责来定义
对于body有没有的情况,也不是绝对的,GET可能也有body,只不过很少见,POST也可以没有body,也比较少见
**如果谈到GET和POST有什么区别?(面试题)
没有本质区别!使用GET的场景,替换成POST一般也可以,反过来也行
但是,没有本质区别,不代表没区别!
两者在使用习惯上有区别:
1.GET习惯上用来表示"获取一个数据",POST则用来表示"提交一个数据"
2.GET一般没有body,需要携带数据就放到URL中,POST一般有body
3.GET请求通常会设计成幂等的,POST则无要求
4.GET是可缓存的(前提是幂等),而POST则不能
5.GET请求可以被浏览器收藏,而POST不能
**
幂等:如果输入一定,得到的输出也一定,这种情况就可以认为是幂等的
比如牛吃进去的是草,挤出来的是奶
如果每次吃进去的都是草,并且每次挤出来的都是奶,就可以说是幂等
如果每次吃进去的是草,挤出来的不都是奶,就不是幂等
幂等性,在开发中也是很关键的,设计成幂等之后,请求就可以缓存了
怎么理解缓存呢?
比如1×10 我可以一秒就说出来是等于10,不是因为我脑子快,而是我记住了,因为只计算了一次,我就记住了,后续我再被问1×10,我可以张口就来
缓存可以提高响应速度,节省运算资源
比如别人问,牛吃了草,挤出来了什么?
我可以一下子就说出是奶,我不用再现去查挤出来的是什么,张口就来就是提高了速度,不用再拿手机查,就是节省了运算资源
缓存无处不在,既可以在客户端,也可以在服务器
浏览器本质上也是一个程序,在cpu上运行的一系列指令,很有可能cpu也把120给记录下来,后续如果再需要计算5的阶乘,都不许要访问其他设备,自己就知道了,这也是一种缓存
URL
URL--唯一资源定位符,描述了网络上的唯一的一个资源
这个概念严格的说,并非是HTTP里的概念,很多协议都会用到URL
URL的结构如图
版本号
最常见的是HTTP/1.1,这也是最主流的版本,绝大部分的互联网上的网站用的都是1.1
还有HTTP/1.0 HTTP/2 HTTP/3
后两个版本对HTTP的功能做了很多扩充
请求头(header)
最后三行应该是一行,只不过太长了,换行了,可以在文件里取消换行
这里的键值对,可以有N行,会用空行作为结束标记,空行就类似于链表的null
header中的键值对,大部分都是http协议规定的,当然这里也是可以添加自定义的键值对
Content-type和Content-Length
Content-type 描述了body的数据格式
Content-Length 描述了body的长度(字节)
这俩属性,跟着body走的,如果是一个没有body的get请求,自然header中就没有这俩属性了
有了上述格式的描述,服务器才能正确认识到当前的body,并正确的进行解析
User-Agent
UA主要描述了系统是啥版本,浏览器是啥版本
那么UA有啥作用呢?
Referer
描述了当前这个页面,从哪个页面跳转过来的
如果直接在搜狗主页的地址栏输入url,此时请求中没有referer,如果点收藏夹,效果也一样,如下图,请求的header里就没有referer
假如你从搜狗的页面输入一个信息,然后你到了你想要的信息的页面,就可以看到referer就是sougou主页,因为是从搜狗主页跳转过来的
举个例子
Cookie
Cookie的本质是浏览器在本地存储用户自定义数据 的一种关键机制
由于网页有很多,我访问搜狗,是需要存一些数据,访问百度也需要存一些数据,针对这种情况,做法是分开,每个网站都存自己的cookie,cookie是按照域名为维度进行存储的
同一个网站(搜狗的主页,搜狗的结果页,搜狗的图片)都共享一份cookie
不同网站(百度,美团,淘宝)则是各自有各自的cookie
那么针对cookie有三个问题
1.cookie从哪里来?
从服务器来的,当我们的浏览器访问服务器的时候,服务器就会在http响应中,通过Set-Cookie字段,把Cookie的键值对,返回给浏览器,浏览器收到这个数据,就会在本地存储
2.cookie到哪里去?
会在下次请求的时候,把cookie带给服务器,cookie在浏览器这边只是暂存,真正要让这个数据发挥作用,还是得由服务器来使用
3.cookie有啥用?
cookie是浏览器本地存储数据的机制,存储的不一定非得是角色,任何想存的数据都行(前提是字符串)
由于cookie存储空间有限,一般也不会用cookie存太大的
cookie这里最典型的应用就是存储用户的身份信息
举个例子
当前在http中遇到的键值对
1.url中的query string
2.header部分,每一行都是一个键值对
3.body部分,如果Content-Type为x-www-form-urlencoded或者json,body的内容也是键值对
4.Cookie里面存储的数据还是键值对
这些键值对都是允许用户自定义的
这些自定义键值对,都是http协议留给程序员进行扩展的地方
为什么http能大火,就是因为他强大的扩展性
正文(body)
正文中的内容格式和 header 中的 Content-Type 密切相关.可以理解成就是按照Content-Type的格式类型写的
Http响应首行
状态码这一块是很经典的面试题!!!
首行由版本号,状态码,状态码描述组成
版本号 (和请求相同)
状态码 是个数字,数字来表示这次请求执行成功还是失败,以及失败的原因
(比如我用海尔洗衣机,中涂出错了,洗衣机显示一个E02,我就去查了一下,原来E02是错误的标志,什么出错呢?是甩干的时候洗衣机盖子没盖好的标志)
状态码描述 通过一个或者一组单词,描述这个状态码的含义
Http的状态码非常繁多,是因为HTTP遇到的情况太复杂了
虽然上述的状态码很对,但是常见的就几个
(1).200 OK 表示的是请求成功
(2).404 Not Found 表示要访问的资源不存在
(3).403 Forbidden 访问被拒绝(无权限)
(4).500 Internal Server Error 服务器内部错误
这个状态码你在互联网上不常见,但是在你自己写代码的过程中非常常见,比如你的服务器bug了,抛了异常但是没有catch到,就会500
(5).504 Gateway Timeout 服务器访问超时了
浏览器给服务器发送请求,服务器就要返回响应,结果服务器迟迟没响应
(6).Move temporarily 临时重定向
Moved Permanently 永久重定向
重定向:访问旧的地址,被自动引导到新的地址上
临时重定向就是我这次重定向了,下次要不要重定向不确定
状态码虽然很多,但是总的可以分成几个大类
(7).418 I am a teapot 这是个特殊的状态码,是个彩蛋
,比如你在百度搜索黑洞,会先出来个黑洞的动画,这个动画就是个彩蛋
后面的Header和Body就和请求没啥区别了,具体参照请求做参考
如何去构造HTTP请求
1.直接通过地址栏,输入一个url,然后就会构造出一个get请求
2.html中,一些特殊标签,也会触发get请求
例如link,script,img,a
比如有个页面中,有一个img标签,此时当页面被加载好了之后,浏览器就会根据标签的src属性,给服务器发起一个get请求,来获取图片内容(想触发get请求需要是个网络资源,如果是个本地资源,就不会触发get请求)
3.form表单,可以触发get请求和post请求
form只支持get和post,其他的http方法就无能为力了
(4).ajax[重要]
ajax 全称 Asynchronous Javascript And XML
ajax是一种前端和后端异步交互的一种方式
什么是异步呢?
不如我去饭馆吃饭,跟老板说,我要个蛋炒饭,如果我一直在窗口等老板做好了,这就是同步
如果老板坐着的时候,我做桌子上玩手机,等老板端上来,就是异步,就是老板做好了那一刻我没有立刻拿到
js提供了原生的ajax的api,这个api贼难用,这里用jquery里面提供的ajax的api
success表示如果请求成功之后,我们要通过一个回调函数来处理响应
回调函数就是不会立刻去调用,而是在后面合适的时机再去调用
相比之下,ajax的功能比form更丰富更灵活
form则允许跨域
构造http请求,不仅仅js,ajax可以构造,任何一个可以操控网络的语言,像java,c++都可以
上述构造请求都需要写代码,是否有办法能不写代码就能构造请求呢?当然有!!!
有一些现成的工具,可以直接构造出http请求
这里用postman
postman还可以自动生成代码
以上就是HTTP的基本内容了,用一张图来说就是
HTTPS
HTTPS是基于HTTP的,仅仅比HTTP多了一个"加密层"
为啥要有HTTPS呢?
就是上面提到的运营商劫持问题
为了能够改善上述问题,就引入了加密,因此HTTPS就应运而生了
加密涉及到了密码学,由于我们对密码学并没有太多的了解,所以我们就不讨论具体的细节算法,只考虑宏观的流程
加密分为
对称加密:只有一个密钥:key
明文+key==>密文
密文+key==>明文
加密解密使用同一个密钥,对称加密的特点就是算起来比较快速
非对称加密:需要两个密钥,一个是公钥(public),一个是私钥(private)
明文+public==>密文
密文+private==>明文
或者
明文+private==>密文
密文+public==>明文
公钥和私钥是对称出现的,用一个加密就用另一个解密
非对称加密相比对称加密消耗的资源更多,效率更低
HTTPS是如何去保证数据安全的?
HTTPS的基本工作过程就是加密:针对HTTP的各种header和body加密,分三步
第一步.使用对称密钥
理想状态
但是可能有黑客从中间截获,但是下图这种情况也是安全的
但是服务器对应的客户端不是只有一个,不同的客户端,使用的密钥,是否是一样的呢?
但是问题又来了
于是就有了
第二步,使用非对称加密
相当于公钥把[key和被key加密的数据]给加密了,然后服务器用私钥把公钥给打开了,然后获取到了key,进而获取到了被key加密的数据,当第一次服务器获取了这个key之后,这个非对称密钥就可以不用了,因为第一次的时候key有公钥保护,黑客没有拿到key,后续就更拿不到了,因为这个时候key以及被服务器获取了
客户端和服务器的业务数据传输,仍然是使用对称加密的方式,因为对称加密速度快,成本低,为了保证对称密钥能够安全到达服务器,引入了非对称加密来保护对称密钥,非对称加密在对称加密传输完成之后,就可以不要了,这就保证了数据安全,同时性能也不会受太大的影响
相当于
B想玩A的游戏号,可是C也想玩,但是A不想给C,这时候A用嘴巴说话告诉B,我的密码是111xxxxx,本来密码有8位,现在只说了3位,因为A发现了C在偷听,为了防止C偷听,A可以发微信告诉B剩下的密码,这时候C就听不到了,然后B就可以随时登录A的游戏号了
你以为这样就安全了吗???
当然不是!安全是相对的,黑客也不是吃素的,下面我们来看一下黑客通过来骗来偷袭的方式,如何骗到了客户端
上述情况,黑客在中间的操作,客户端和服务器都是感知不到的,我们把这样的操作就叫做中间人攻击
而中间人攻击,破解的关键就是要让客户端能够信任公钥!如果客户端能够识别出这个公钥是不是服务器本身的,那么问题不就迎刃而解了嘛
第三步 引入证书
这个证书不是纸质的证书,而是一串数据(类似于一个对象,里面有很多属性),是一个数字证书。
假如我现在有一个服务器,我就需要去这个机构里申请证书,申请的时候,当然要提交一些材料(甚至要交钱),机构进行审核,审核通过了,就颁发证书。
提交资料的时候,服务器的公钥,也一起提交过去,此时,证书中就包含了服务器的公钥
现在一共涉及到了5把密钥
客户端生成的对称密钥,用来加密数据
服务器生成的非对称密钥pub和pri,用来加密对称密钥
颁布证书机构的非对称密钥(pri,权威机构自己持有这个私钥)
客户端电脑系统内置的权威机构的公钥,用来加密证书的签名
上述的这一套:对称加密+非对称加密+证书这一套流程,叫做SSL(也叫TLS,两者是一个东西)
SSL也是一个协议
总的来说HTTPS=HTTP+SSL
不仅在HTTPS中涉及到SSL,其他场景也会用到SSL(比如SSH协议,JDBC编程等)
面试题
1.http响应首行状态码那里 ,基本必考
2.HTTPS的加密过程