1)HTTP协议是倾向于相遇业务层次上面的一种协议,传输层协议主要考虑的是端对端之间的一个传输过程,TCP重点进行关注的是可靠传输;咱们的HTTP/1,HTTP/2是基于TCP的,但是咱们的HTTP/3是基于UDP的,但是当下的互联网绝大多数都是使用的是HTTP/1.1;
2)但是咱们的应用层协议,主要是站在程序应用的角度,要对传输的数据,做出具体的应用
3)咱们的应用层协议,很多的时候,是咱们的程序员进行自定制的,我们要根据合适的业务场景来进行设计协议,在程序员这个圈子里面,有些大佬就设计出了很厉害的协议,让咱们的程序自己进行使用,HTTP协议是一个典型代表;
4)HTTP虽然已经是自己设定好的,但是HTTP协议本身的可进行扩展的能力是非常强的,我们就可以根据实际的需求,来程序员来进行传输各种自定义的数据信息;
协议格式:数据具体是如何进行组织的
1)UDP/TCP/IP这些协议都是属于二进制的协议,也就是说我们经常要理解到二进制的比特位,要想要理解到某一个协议格式,要具体理解到某一个比特位;
2)HTTP则是一个文本格式的协议,不需要去理解具体的二进制位,而是只是需要理解到具体的文本的格式即可,更方便人去理解;
服务器和客户端的交互,分为以下四种模型:
4.1) 一发一收:请求和响应是一一对应的,HTTP协议就是针对这种模型的;
4.2) 多发一收:典型的要传输一个具体的大文件,也就是说多个请求对应到一个响应,要把大文件分成一个个的小文件,多个请求对应到一个响应;
4.3)一发多收:一个请求得到很多响应,例如想要看直播,系统不知道我要看那个直播,就会返回很多响应,返回响应有很多直播供我们来进行选择;
4.4)多发多收:多个请求得到多个响应;
1)HTTP协议:是应用层使用的一种十分广泛的应用层协议,他的全称是超文本传输协议,所谓的超文本,意味着传输的内容不仅仅是文本(例如html,CSS就是文本),还可以是一些其他的资源,例如图片,视频,音频,链接等其他二进制数据,我们使用Servlet是一个构建动态网页的技术,但是HTTP协议是我们前后端进行沟通的一个桥梁;
2)当我们在浏览器中输入一个网址,此时浏览器就会给对应的服务器发送一个http请求,对方服务器收到这个请求之后,经过计算处理,就会返回一个http响应,这就完成了客户端进行和服务器的一次交互;
3)例如当我们在网络上输入一个网址想要获取搜狗主页,这时就会发一个http请求,经过搜狗服务器的计算之后,这时搜狗的服务器就会返回一个搜狗主页的html;
抓包:咱们的抓包工具就是相当于是一个第三方的程序,在这个网络通信过程中就类似于代理一样,请求和响应都是要经过代理的,因此通过这个抓包工具就可以获取到请求和响应的详细内容数据
1)抓包工具的原理:抓包工具相当于是一个代理工具,例如当浏览器访问sougou.com的时候,就会先把HTTP请求发送给Fidder,Fidder然后就会把请求发送给搜狗的服务器,当搜狗服务器返回数据的时候,Fidder就会拿到返回数据,再把数据交给浏览器;
2)通过Fidder我们就可以看到请求和相应的详细格式和信息,我们点击刷新之后,我们就会发现抓到的HTTP的请求和响应是非常多的,本来一个复杂的网页,就会与服务器之间进行多次交互的,加载一些图片,字体,以及一些CSS;
3)例如我想要访问搜狗主页,此时用Fidder进行抓包,里面有一条特殊的颜色,这就说明返回了很大的数据,这一条请求就是获取搜狗搜索页的请求和响应,Fidder会自动的帮我们进行解密;
正向代理:
1)例如我想要做饭,需要一包盐,但是我懒得买,我就想要让我的弟弟代我去买,这里的过程如下:我把钱交给我弟弟,真正与超市老板交互的是我的弟弟
2)这里面的我就是客户端,超市老板就是服务器;本应该我与超市老板进行交互,但是却换成了我弟弟;站在超市老板的角度来说,站在服务器的角度来说,它并不需要关心真正的客户端是谁,只要单纯的完成买盐的动作即可,也可以这么说:我的弟弟把我隐藏起来了,服务器只能看到我弟弟,看不到真实的我,站在服务器的角度,把客户端隐藏起来了;
反向代理:
站在客户端的角度,把服务器隐藏起来了,我还是想买一包盐,我去超市买盐,结果出来的是超市老板的儿子,超市老板把盐给儿子,我此时并不关心真实的服务器是超市老板还是他儿子,客户端只能看到他儿子,看不到真实的老板
1)咱们的上面的这些Fidder的抓包的这些标签页的选项,其实本质上就是说我们当前使用了什么样子的格式来进行显示这个HTTP请求,咱们使用最多的就是这个raw选项;
2)这个raw选项,我们在这里面看到的就是HTTP请求数据的本体,选择其他的选项,就是相当于Fidder对数据整体进行了一些加工,调整了一些格式;
3)上面就是咱们的HTTP请求的原始摸样,如果说你向TCPSocket里面,按照上面的格式来进行构造数据,并且写入到Socket里面,其实本质上就是构建了一个HTTP请求
4)当我们看到响应报文的时候,发现看到的二进制返回的数据好像是乱码?乱码其实本质上就是压缩之后的结果,咱们的一个服务器本质上来说最贵的就是网络带宽,像咱们的HTTP响应,通常是会很大的,就比较占用网络带宽,但是能够为了提高效率,经常服务器返回压缩之后的数据,咱们的浏览器收到返回回来再来进行解压缩;
通常我们点击这个Response body is encoded,Click to decoded;
一:HTTP客户端请求的基本格式
HTTP请求:是一个行文本,一行一行的组织数据,每一行都有特定的含义
HTTP的请求和响应都而是对应着一定的格式的:
HTTP请求格式:
1)首行:方法 + url + 版本号(虽然首行比较长,但是里面分成了三个部分,使用空格来分割);
2)首部请求头(header):这里就是一堆键值对,键值对和键值对之间,使用换行来分割,每一个键值对占一行,键和值之间,使用冒号+空格来分割,header中有多少行,是不确定的;具体是使用一个空行来作为结束标记
请求报头的Key: Value
请求报头的Key: Value
3)空行:用过这个空行来表示header结束了
4)正文body:空行后面的内容都是Body,Body允许是空字符串
如果Body存在,就会在Header里面有一个Content-length属性来表示Body的长度
HTTP响应格式:
1)首行:版本号 + 状态码 + 状态码的解释,他们彼此之间也是使用空格来分割,不同的状态码会有不同的状态码的描述
2)协议头(header):表示请求的属性,冒号+空格来分割键值对;每一个键值对占一行,遇到空行表示Header部分结束;
响应报头Key:Value
响应报头Key:Value
3)空行;
4)Body:空行后面的内容都是Body,Body里面的内容允许是空字符串,如果Body存在,就会在Header中包含一个Content-length的属性来表示Body的长度,如果服务器返回了一个html的界面,那么这个界面的内容就是在Body中
1)为什么这里是一定要有空行的?
因为HTTP协议在本质上是并没有规定报头部分的键值对到底有多少个,空格就相当于报头的结束结束标记,或者是报头域正文之间的分隔符;再说,HTTP在应用层依赖TCP协议,TCP是面向字节流的,如果没有这个空行,就会出现粘包问题;
2)HTTP版本号包括:HTTP/1.1和HTTP/1.0
我们来进行使用Fidder的一些小技巧:
1)咱们的Fidder左侧的列表会一直抓到新的结果,会快列表就会很大,因为很多网站都在不同的和服务器之间进行交互,甚至你电脑上面的某一些程序都在偷偷的在和服务器之间进行交互
2)很多时候我们要去进行清屏操作,我们就需要ctrl+a进行全选,然后再按住delete进行删除
这不是说抓包失败,而是抓到了一个请求失败的包
一)HTTP请求中的URL,含义就是表示网络上面唯一资源的地址符
1.1)它是用来描述一个网络资源在主机上面的的具体位置,要明确主机是谁,又要进行明确我们是取出网络上面的哪一个资源;
1.2)其实我们通过浏览器,打开网页的时候,地址栏里面填写的地址其实本质上就是一个url
1)协议方案名:描述了说当前的URL是来给哪一个协议来进行使用的,比如说http://就是给HTTP用的,https://是给HTTPS用的,jdbc:mysql://是给jdbc:mysql用的,url是给很多协议来进行使用的,常见的协议名有FTP,HTTPS,jdbc:mysql://可以这么说URL不光仅仅给HTTP协议提供服务,还可以给很多协议提供服务;
2)登录信息:上古时期上网的时候会体现出用户名字和密码,带有登录信息的URL其实现在已经很少见了,现在的登陆一般都是直接搞一个登录界面,在登陆界面里面再去填写用户名和密码,以表单或者ajax的形式来进行提交
3)服务器地址:可以是域名(方便记忆方面传播),还可以是IP地址,表示的是说当前咱们要进行访问的主机是什么?后面可以用一个/来进行分割,IP地址和域名是一一对应的关系,咱们的域名可以经过DNS服务器转化成IP地址;
4)服务器的端口号:表示咱们要进行访问目标主机上面的哪一个应用程序,咱们的这个端口号大部分情况下是省略的,省略的时候不是说没有而是因为浏览器会赋予一个默认值,对于HTTP协议开头的url来说使用的端口就是80端口作为默认值,对于HTTPS的url来说,端口就是被默认指定成为了443,对于一个服务器,绑定的是哪一个端口,这个可是不一定的,如果对方服务器绑定的不是默认端口,那么此时就需要修改了;
5)带层次的文件路径:表示访问服务器上面的不同的资源,一个服务器程序上有很多的资源,我们来找到到底是哪一个资源,也就是要访问的服务器的资源是什么?例如有很多的HTML,有很多的图片,CSS和JS,这个路径往往是带有层次结构的,可能会有一定的目录结构,通过这个目录一层一层的往下找从而找到具体的文件,但是我们还是需要进行注意一下,虽然我们在请求的url里面写的是一个文件路径,但是这个服务器上面对应的却有可能不是一个真实的文件路径,这个文件路径可能说是在磁盘上面的,是一个真实的文件,但是还是有可能是说这个文件路径是由咱们的服务器来构造出来的一个动态数据;
总结:上面的IP地址+端口号+带有层次的文件路径就描述了说一个网络上面的具体的一个资源,IP地址描述了说我们到底要去哪一个快递公司,端口号描述了说我们要去找到快递公司的哪一个工作人员,而我们的带有层次的文件路径就是明确快递公司人员发的取件码
其实我们在定位网络上的一个具体的资源的,还可以带有其他一些详细的要求,也就是后面的参数部分
6)查询字符串:本质上来说就是咱们的浏览器或者是客户端向服务器传输的自定义的信息,相当于是对获取到的资源提出了一些更高的要求,我们只能看清这里面的格式是什么样子的,但是我们没有办法理解里面键和值都是什么意思,只要特定开发这个应用的程序员才能认识
7)URL中的片段标识符:不是特别常见,通常用于定位HTML页面中的具体位置,这个在文档类网站中,十分常见,以#来进行开始,就是描述了说当前我们要进行访问的html页面中的哪一个具体的子部分,能够控制到浏览器滚动到相关位置,就是类似于快速定位的效果,比如说小说网页,文档网页,一个页面里面有很多的章节,很多的子标题这种,其中我们就可以通过片段标识符来进行跳转到某一个标题或者是某一个片段里面,可以通过片段标识符跳转到一个文档上面的不同章节;
URL的初心就是用来区分网络上的唯一资源:
1)先通过服务器地址,定位到一个具体的服务器;
2)再通过端口号来定位到一个具体的应用程序;
3)再通过路径来定位到应用程序来管理的一个具体资源;
4)再通过查询字符串,对具体资源的要求做出进一步的解释
5)再通过片段标识来确定到定位这个资源的哪个部分;
我们就是说先通过url给定的路径在服务器这里面准备一些相关的资源,然后再根据这里面的查询字符串传递的一些参数再对这些资源来进行处理,进行筛选;
urlncode:当我们的queryString里面出现了特殊字符的时候,我们就需要对特殊字符进行转义,这个转义的过程,就叫做urlencode
1)反之如果说我们是把转移的内容进行还原回来,就叫做urldecode,因为咱们的url里面是有很多的特殊含义的符号的,比如说: / ? = &都是具有一定的特定含义的
2)如果浏览器和服务器解析这个URL的时候,就是把URL中的各个部分取出来组织成结构化的数据;
1)在URL当中,有些东西是用户自定义的,典型的就是query string,用户自定义的query string中,是存在着一些特殊符号的: / ? = &,如果query string中也包含着上面的特殊符号,就可能会导致浏览器/服务器进行解析URL的时候出错;
2)例如本来人家程序上面是判定?后面的部分是query string 但是在你的结果里面也有一个?
本来这个?是来进行分隔路径和查询字符串,https://www.sougou.com/web??&_ast?=123456789,咱们的url就不知道从哪里到哪里是完整分割的一部分,我们就把这个特殊和url一样的字符进行转义,避免冲突;
3)稳妥情况下,我们应该让后面的querystring,不要出现或者包含特殊字符,要是querystring针对特殊字符,直接进行转义(浏览器自动进行转义)
把特殊字符转化成转义字符,叫做URL encode
把转义字符转化成原来的字符,叫做URL decode
除了特殊字符之外,像汉字之类的也要进行URL encode;
下面我们是在搜狗主页输入一个?所构造出来的一个URL;
? - 搜狗搜索https://www.sogou.com/web?query=%3F&_asf=www.sogou.com我们可以看到query=%3F这个就是表示用户输入的查询词,%3F就是URLencode的结果,所谓的转义,就是把这个特殊符号里面的值,按照16进制来进行表示,每一个字节前面加上一个%;
C++ - 搜狗搜索https://www.sogou.com/web?query=C%2B%2B我们在这里面输入C++,浏览器会对+这个字符进行转义,这里面的+对应的ascii的十六进制恰好是2B,也就是说当我们在搜狗页面上面搜索C++的时候,就可以看到url里面的querystring里面,就有了一个键值对,里面就包含了查询内容,这里面的+其实本质上就是针对+本身进行urlencode之后的结果
鲜花 - 搜狗搜索https://www.sogou.com/web?query=%E9%B2%9C%E8%8A%B1在里面输入鲜花,这里面采用了UTF-8编码
所以我们在自己写一个URL的时候,要自己进行URLencode