(一).应用层协议
1.基础概念
应用层,是程序员打交道最多的层次。和应用程序相关,程序员写的代码只要涉及到网络通信,那么都可以视为应用层的一部分。
对于应用层中涉及到的网络通信协议,很多都是由程序员自定义的,即在写代码的时候,自己创造出来的协议。
2.自定义协议的制定
自定义协议分成两个阶段
阶段一:根据需求明确要传输的信息
客户端 和 服务器 传递的信息
就拿点外卖来说吧。当我们点开“某团”之后,首先会根据我们自身的地理位置进行展示一个商家列表。
这里“请求”数据:用户的位置信息和用户id
这里“响应”数据:商家的id,商家的名字,商家的图片等等
阶段二:约定好信息组织的格式
①.行文本(早期)
将用户的数据和商家的数据都以行文本的形式进行请求和响应
用户id,用户的位置 \n
10000,45E45N \n
商家id,商家的名字,商家的图片
1,杨某福,1.jpg
2,麦某劳, 2.jpg
3,肯某基,3.jpg
4,必某客,4.jpg
上述的方案,列与列之间不一定使用,也可以使用. 也可以使用\t
是我们自定义的协议,只要客户端和服务器都按照这同一套规则来进行构造和解析数据即可
缺点:可读性差,单看一个数据不知道是干什么的
②.通过xml格式来约定
xml和html类似,都是采用成对的标签构成的键值对结构。只不过html不能乱写标签,xml标签内容都是自定义的
请求
<request>
<userId> 1000 </userId>
<position> 45N45E</position>
</request>
响应
<response>
<shop>
<id>1</id>
<name>杨某福</name>
<img>1.jpg</img>
</shop>
</response>
注意:这些数据只是用来网络传输,和浏览器怎么显示无关,浏览器的显示是由html来约束的
优点:可读性好
缺点:冗余信息太多(标签太多),在网络传输的过程中,会消耗更多的带宽
③.通过json来约定
json是当下最流行的网络数据格式组织的方案
请求
{
"userId":10000,
"position":"45E45N"
}
响应
{
"id":1,
"name":"杨某福",
"img":1.jpg
}
优点:可读性好,消耗的带宽相对于xml来说,更节省
缺点:存在冗余信息
④.通过protobuf来约束
protobuf是基于二进制的格式,读数据进行压缩,不涉及到json和xml的冗余信息,带宽消耗的也少了,但是可读性变差了。主要用于高性能的场景中

(二).http协议
1.基础概念
在应用层中,除了程序员自定义的应用层协议之外,还有一些已经搞好了的协议,例如http,ftp,ssh等等,这里主要介绍一下http协议
http协议是当前进行web开发中最核心的协议,使用网站都会使用http协议。同时现在还有一个https协议,https协议相当于http协议加了一层“安全层”,这个https协议后面再进行介绍,这里主要介绍http协议
http协议属于“一问一答”模式的协议,即客户端发送一个请求,服务武器就返回一个响应。请求和响应是一 一对应的
在网络通信中,还有其他的模型。比如,多问一答,典型场景是上传大文件,在上传大文件的时候,会将一个大文件拆成若干个小的文件进行上传;一问多答,典型场景是下载大文件,在下载大文件的时候,会将一个大文件拆成若干个小的文件进行下载;多问多答,典型场景就是远程控制电脑
2.http的报文格式
(1).预备知识
在介绍http的报文格式之前,我们需要搭配一个“抓包”工具,能够获取到网络的数据包,然后将数据包的格式都解析出来。这个“抓包”工具相当于“代理”。
下面通过一个例子来介绍一下“代理”
中午十一点半,我打开了“某团”,然后点了一个“兰州拉面”,我点的这个“兰州拉面”,由于我不想去商家店里拿,所以我就找了个骑手给我送过来,对于这个骑手来说,我和这个店家之间的交易,骑手是非常清楚的,此时这个骑手就被称为“代理”

同时,这个骑手是为我服务的,那么这个骑手就被称为“正向代理”
如果代理是给客户端干活,那么就被称为正向代理
如果代理是给服务器干活,那么就被称为反向代理
(2).fidder抓包工具
这里我们使用的抓包工具是fidder,fidder是专门用来抓http的

由于现在的数据包大多数都是https协议的,所以说,下载完fidder之后,要进行配置一下,具体配置方法按照上图进行配置

在fidder的左侧窗口中,显示的是当前请求/响应的列表

当我刷新了一下CSDN之后,上图就是fidder抓到的部分包,其中 红色的表示报错,蓝色的表示这个请求得到了个网页,绿色的表示得到了一个js,灰色的表示这个响应的数据已经被缓存了,紫色的表示得到了一个css

我们选择红色方框的包,这个包就是csdn的网页,因为首先,这个与其他的包颜色不一样,同时body的大小,也是比较大的,那么这个包就是一个比较重要的包

同时,上面有一些标签页

我们要选择蓝色框出来的标签页
然后下面的界面中现实的就是请求的原始数据

如果觉得太小,可以点击右下角的“View in Notepad”选项

请求的数据就可以在记事本中打开了

在“响应”中也要选择“raw”选项
当我选择“View in Notepad”选项后

打开记事本之后,发现是一堆乱码。这是因为,响应数据为了节省网络的带宽,同时是将数据压缩后传输的

如果要看压缩之前的数据,那么就点击红色方框的选项,然后再点击“View in Notepad”选项

可以看出,服务器返回的是一个html响应
(3)."请求"报文格式

(4)."响应"报文格式

Http协议是一个“文本格式的协议”
请求 响应
①.首行 ①.首行
②.请求头 ②.响应头
③.空行 ③.空行
④.正文 ④.正文
3.详细介绍报文格式的每一部分
(1).URL
在数据库的最后介绍JDBC的时候,我们创建完DataSource源对象后,设置了URL,user,password
URL,就是用来描述网络上的唯一资源的位置的
在JDBC中,我们创建URL的时候用的是
jdbc:mysql:/127.0.0.1:3306/java113?characterEncoding=utf8&userSSL=false
同时现在我在CSND中搜索了个“你好”,URL就这样的
http://so..csdn.net/so/searchspm=1000.2115.3001.4498&q=%E4%BD%A0%E5%A5%BD&t=&u=

可以通过一个例子来具体理解每个参数的含义
假设,我现在要去吃一碗杨某福麻辣烫,然后这个杨某福麻辣烫在我们学校的位置是 “1餐厅,18号窗口”,然后我现在去了之后,选完了菜之后把菜给了服务员,然后告诉服务员说“麻辣烫和麻辣拌,我选择要麻辣烫,骨汤味的,同时不要香菜,不要葱”
那么转换成https协议之后就是
https://1餐厅.18/杨某福麻辣烫/麻辣烫/骨汤味?葱=不要&香菜=不要

这是原始的http协议的格式,同时里面的登陆信息部分,现在不会写在URL中
对于 “#ch1”片段标识符,在文档文件中见到的比较多


上图是我在查看Vue开发者文档中,选择不同部分,查看到的不同的片段标识符
所以,片段标识符主要是用来表示文档中的不同部分
(2).urlencode
urlencode的主要作用就是将Query String中数据的二进制内容按照字节为单位取出来然后转义为十六进制表示,前面加上%。这样做的目的是避免出现可能让url解析出错的特殊符号

当我搜索“c++”的时候,URL中显示的是 “c%2B%2B”

当我搜索“JAVA”的时候,URL中显示的“JAVA”

当我搜索“你好”的时候,虽然在URL中显示的是“你好”,但是通过抓包工具抓到的结果来看,显示的是“q=%E4%BD%A0%E5%A5%BD”
通过上述的三个例子,我们可以发现,对于英语系的文字,在发送请求的时候,是没有变化的,对于非英语系的文字,例如,标点符号,中文等等,都是进行转义的。只不过有些浏览器为了客户端看起来方便,显示的是转义之前的内容,实际上通过抓包工具看到的,都是转义之后的
这是因为在URL中本身也是有一些特殊的符号,然后分别对应的不同的含义,例如 : , / , ? , # 等等,由于Query String中的内容,是程序员自己定义的,为了避免query string中的特殊符号影响到URL,所以将query string中的特殊符号进行了转义,这就是urlencode的作用
(3).认识“方法”
Ⅰ.基础概念

上图中的所有方法,最重要的是GET和POST方法,其次是PUT和DELETE方法
对于GET和POST来说,是最常见的请求
从语义上说,GET是只读查询资源,POST是提交,新增,修改资源。实际上在写代码的时候,不一定会严格按照语义来进行区分
对于获取html,css,js等操作都是GET
对于登录,上传文件,典型的使用POST

当我刷新CSDN之后,发现基本没有获取css和js的包
注意,这时候刷新要按住ctrl再刷新

当我按住ctrl再刷新之后,发现,就获取到了css和js的包,紫色的就是css,绿色的就是js


这里按住ctrl再刷新的原因是
如果直接刷新,则表示重新访问服务器,如果是按住ctrl再刷新是强制刷新,忽略本地缓存,所有资源都重新从服务器获取
这跟浏览器的缓存机制有关,对于浏览器从服务器或者通过网络加载网页来说,通常情况下,从网络加载数据要比从硬盘加载数据要慢。所以说,浏览器为了加快访问页面的速度,就会把页面依赖的一些静态资源,例如css,js,图片等等,这些内容缓存到硬盘上,等到下一次访问的时候就不用重新加载了,只有第一次访问服务器的时候,加载这么多东西
注意:GET请求一般是没有body的,当通过GET给服务器发送一些数据的时,会通过URL中的query string 传递过去
Ⅱ.POST的两个典型场景
①.登录
②.上传。在上传的时候,请求是带有正文的。正文就保存了当前要上传的数据的内容。对于图片来说,图片本身是二进制的,但是通过特殊的方式进行转码,例如base64,把二进制转成文本,其实body中也是可以填二进制的
Ⅲ.GET和POST的区别(面试题)
GET和POST从HTTP规范设计意图上看,本质上还是存在区别的。从传输数据的机制上看是没有本质的区别x的,经常可以进行混用。从使用方法习惯上来说,主要有以下方面的区别:
①.GET是只读查询资源,POST是提交,新增,修改资源,但是POST和GET在语义上可以进行混用。
②.携带数据的方式不同。POST是带有body的,但是也可以带有 query string;GET是带有 query string 的,但是也可以带有body,只不过比较少见。
③.GET请求通常建议设置成“幂等”的,POST无要求。对于“幂等”,即请求是一定的,得到的响应也是一定的,即多次执行同一个请求,对服务器资源产生的影响和执行一次完全一样
④.GET设置成“幂等”后,由于请求是一定的,得到的响应也是一定的,所以就可以允许GET请求的结果默认被缓存;POST请求由于不要求“幂等”,经常是不“幂等”的,那么就认为请求的结果默认不缓存
⑤.POST比GET更安全。这是因为在登录场景中,用户会输入用户名和密码,由于GET是带query string的,所以会将用户名和密码直接显示到URL中。但是对于POST来说,是带有body的,会将用户名和密码放到body中,但也不是绝对的安全。黑客随便抓个包就获取到了。所以针对于是否安全,还是需要进行加密传输
⑥.GET传输的数据有长度限制。这是因为之前在使用IE浏览器的时候,IE浏览器对于URL的长度是有限制的。由于GET传输的数据是在URL中,所以就会导致传输的数据太多了,此时就会发生截断。现在主流的浏览器早都没有这样的限制了。
⑦.GET只能传输文本,POST可以传输二进制。GET确实在URL中只能存放文本,但是可以把二进制通过base64转码成文本
Ⅳ.PUT和DELETE
对于PUT和DELETE,使用的场景不是很多,会在实现Restful风格的api的时候,会用到
Restful风格的api是设计服务器接口的一种“习惯”
如果是给服务器新增一个资源 ,则使用 POST
如果是给服务器删除一个资源 ,则使用DELETE
如果是给服务器修改一个资源 ,则使用PUT
如果是给服务器查询一个资源 ,则使用GET
上面的这四个操作,任何一个都能完成增删改查,主要是取决于代码如何写
对于Restful风格,不仅约定了方法,还约定了路径,及路径的组织,还约定了返回的结果的响应该如何组织
这些在后面会做出介绍
(4).报头(header)
Ⅰ.基础概念
报头中的每一部分都是键值对结构。报头中分为很多行,每一行都是一个键值对,键和值之间使用: 进行分割(注意,:后面有一个空格)。每个键值对都是标准规定的,这个标准叫做“RFC标准文档”

上图是我通过fidder抓取的访问搜狗引擎的包,红色方框框出来的部分就是报头
Ⅱ.Host
表示服务器主机的地址和端口,即当前请求访问的服务器在哪里

上图中没有端口号,这是因为使用了Http的默认端口号
这个Host中的内容在绝大部分的情况下,和URL中的ip地址(域名):端口号一样,但是也有特殊情况,例如使用了代理服务器,当使用代理服务器时,代理服务器就会将URL中的ip地址进行修改, 此时就是这个请求先发给代理,然后代理再发给服务器。其实即使是使用了代理服务器,也是可以通过Host来获取到最原始的目的主机是谁。
在HTTP协议中,传输的时候是可能会涉及到“加密”(HTTPS),但是URL中是不会进行加密的,加密的是header部分和body部分。当服务器接收到请求之后,就会通过URL中的内容和header中的加密的内容进行校验,验证是否一致
注意:如果是登陆密码,则都是在业务层进行加密的,如果只是单纯依赖https,则只会在传输的过程中进行加密,这就意味着如果密码就明文保存在服务器上,服务器就可能被攻击,同时就意味着密码泄露了
Ⅲ.Content-Length
表示body中的数据长度,单位是字节。如果请求中根本就没有body,则就没有Content-Length这个属性。
对于HTTP协议,在传输层是基于TCP实现的(版本号<=2.0),http协议就是把字符串构造成HTTP约定的格式,即将 首行 请求头 空行 正文 这四部分,通过字符串的形式写入到 TCP的Socket对象中。对于TCP来说,我们前面介绍过,一个连接可以发送多个请求,当服务器接收到请求之后,就需要进行区分,区分从哪里到哪里是一个完整的http请求。如果http在进行区分的时候,在header中没有读到Content-Length,那么就意味着没有body,此时读到空行之后就认为结束了;对于有body的请求,先读取首行和header,一直读到空行,然后解析header中的Content-Length属性,根据里面的值,再读取固定字节的长度
Ⅳ.Content-Type
表示请求的body中的数据格式,提示了接收方该如何解析body中的数据
对于http协议来说,能够携带的数据种类还是比较多的
| 种类 | Content-Type | 说明 |
| HTML | text/html | 浏览器会解析其中的标签,把标签转换成界面显示 |
| CSS | text/css | 浏览器会解析其中的“选择器”和“属性”,并且把这里指定的内容应用到页面的样式上 |
| JS | application/javascript | 浏览器通过js引擎解释执行js中的逻辑 |
| JSON | application/json | 浏览器不会做任何处理,由对应的js程序员写的逻辑中 |
| 图片 |
image/png image/jpg | 浏览器尝试按照图片的二进制格式,解析出来并显示 |




Ⅴ.User-Agent(UA)
通过一个示例来了解什么是UA


通过上图中对每一部分的表示,可以发现,整个UA所表示的就是当前支持的浏览器的版本和操作系统的版本,即表示了用户使用的设备的浏览器和操作系统的情况
具体原因是因为①.在互联网发展的早期,一开始浏览器中只能显示文本,后面在网页中加入了图片,各种样式,js,多媒体等等。但是在同一时间内,有些用户的浏览器的版本是比较旧的,支持的功能也少,有些用户的浏览器版本更新,支持的功能多。为了解决这一问题,就引入了UA,根据用户使用的设备进行区分,通过UA中的浏览器版本和操作系统的版本曲阜当前用户的设备最多支持哪些功能。对于老的浏览器,则返回功能少的网页,对于新的浏览器,返回功能多的网页
②.UA可以区分用户的设备。如果用户使用的是windows,则返回PC端的网页,如果用户使用的是android或ios,则返回手机端的网页。如果用户使用的是平板,则在前端中有一个“响应式编程”,通过CSS中的“媒体查询”功能,感知到当前窗口的尺寸,然后通过不同的尺寸,设置不同的样式。
Ⅵ.Refer
描述了当前网页的来源,即这个网页是从哪个页面跳转过来的

上图是我通过搜狗引擎搜索的哔哩哔哩,可以看到Refer
Ⅶ.Cookie
在介绍Cookie之前,我们首先要明确一个概念。
浏览器在展示网页的过程中,虽然页面中可以通过一些js代码来实现一些逻辑,但是js代码无法访问我们硬盘上的文件。其实这也不难理解,假设我们访问一个网页,然后这个网页的js代码将我们硬盘上所有的数据都删除了,那么这不就出问题了嘛,所以说,主要是怕js瞎搞。但是在实际开发中,有的时候还是希望把某些数据保存在到本地的硬盘上,此时浏览器就引入了Cookie的概念。
Cookie就是浏览器允许网页在本地硬盘上存储数据的一种机制,不是让网页代码直接访问文件系统,而是浏览器的cookie提供了键值对存储机制


上图是我重新抓取的搜狗引擎的http请求包
同时,在浏览器中也可以看到Cookie


cookie是按照“域名”维度来组织的。cookie中的内容是程序员自定义的
Cookie刚开始是由后端程序员自定义的,然后通过Set-Cookie自定义生成键值对,发往浏览器,当浏览器保存了这些cookie之后,就会在后续给服务器发送请求的时候,把这些cookie键值对放到请求cookie header 中传输给服务器
我可以对浏览器当中的cookie进行清除,清除的是保存到浏览器当中的数据,我们可以通过刷新页面,这些Cookie就又回来了

比原来少是因为对浏览器的操作太少,只是刷新了一下页面,如果不断地对浏览器进行操作,那么Cookie会越来越多
当我们重新刷新后,重新看请求

发现,已经没有Cookie了,这是因为,我只清空了浏览器中的cookie,即清空的是网站本地所有已保存的Cookie,再刷新页面的时候浏览器发现没有什么可带的了,所以请求头中自然也就没有Cookie 了
对应的响应

发现,有很多Set-Cookie,包含的是要往浏览器中存的数据。对于服务器来说,刷新页面意味着收到了一个全新的请求,所以会给浏览器一个全新的Cookie
对于Cookie来说,Cookie是浏览器在本地持久化存储的一个工具,即使重启浏览器,这个数据仍然存在,但是也不是一直存在,Cookie一般会有一个超时时间

“登录和用户认证”场景

注意:上述过程是服务器和浏览器之间的联动,上面也介绍过,Cookie是可能会过期的,服务器返回Cookie的时候,是可以设置有效时间的,如果Cookie中的sessonId过期了,此时就需要用户重新登陆了。在用户重新登录的过程中,是否需要重新手动输入密码,这个功能是浏览器的功能,和服务器无关
4.HTTP状态码
(1).概念
HTTP状态码,描述了响应的结果,是正确还是错误,如果错误,则错误的原因是什么
状态码都是制定HTTP的开发人员定好了的

上图基本是所有的状态码,这里只介绍几个常用的状态码
(2).具体的状态码
①.200 OK
这是最常用的状态码,表示成功,即访问正常

②.404 Not Found
表示访问的资源没有找到
在URL中,ip地址是用来定位主机的 port端口号是用来定位程序的 path路径是用来定位程序管理的资源的
如果要访问的页面出现了404,则表示path访问的资源在服务器上没有

当我访问搜狗引擎的123.html的时候,返回的响应就是404
③.403 Forbidden
表示访问被拒绝,即没有权限访问

④.405 Method Not Allowed
表示方法没有被允许,当请求的方法和服务器这边声明的注解不匹配,就会出现405。关于什么是注解,后面介绍
⑤.500 Internal Server Error
表示服务器出现错误。如果服务器处理逻辑代码的时候,抛出了异常,但是没有进行捕获,此时就会出现500
⑥.504 Gateway Timeout
表示网关超时,网关,可以简单地理解为网络的入口,网关可以是一个软件,也可以是一个专门机器

2511

被折叠的 条评论
为什么被折叠?



