我们以后主要工作基本上都是工作在应用层的,因此作为程序员可以自定义一个应用层协议,应用层协议主要是对网络传输数据的一种规范,对于自定义协议,主要由以下几个数据格式:
(1)行文本
请求和响应都可以由多行构成,以**/n**作为该行结束的标志,如点餐时服务器返回的响应:
但是现在行文本的数据传输格式已经过时了,很少会使用。
(2)xml
xml和html非常相似,都是成对标签构成的键值对结构,区别是xml中的标签是可以自定义的,而html中的标签都是已经定义好的,如:
xml虽然可读性很高,但是数据冗余很大,非常消耗网络带宽,因此xml这种数据格式也很不常用。
(3)Json
Json是目前使用最多的一种网络数据传输格式,它的格式与JS的写法比较相似,如:
虽然Json也有数据冗余,但是相较于xml好了很多
(4)protobuf
protobuf是基于二进制的格式,对数据进行压缩,不存在数据冗余,但是可读性非常底,一般也不用,除非对性能的要求比较高以及其它一些特殊情况才会使用。
除了程序员自定义协议,有一些现成的应用层协议也被广泛使用,如HTTP/HTTPS
一、什么是HTTP
HTTP是一种非常常用的一个应用层协议,我们平时在浏览器中访问的各种中页面,都涉及到这个协议,当我们在浏览器中输入一个网址时,浏览器就会给对应的服务器发送一个HTTP请求,服务器会给客户端返回一个HTTP响应。
二、 认识HTTP
想要学习HTTP就需要了解HTTP的报文结构,要了解它的报文结构,需要借助抓包工具来观察,下面我们用Fiddler来进行抓包,下载链接:https://www.telerik.com/fiddler/
2.1 抓包工具原理
Fiddler 相当于⼀个 "代理".
浏览器访问 sogou.com 时, 就会把 HTTP 请求先发给 Fiddler Fiddler 再把请求转发给 sogou 的服务 器. 当 sogou 服务器返回数据时, Fiddler 拿到返回数据, 再把数据交给浏览器. 因此 Fiddler 对于浏览器和 sogou 服务器之间交互的数据细节, 都是非常清楚的.
2.2 了解HTTP的报文结构
现在我们来抓一个包,以了解HTTP的具体格式:
抓到的包需要点击上图中红色部分才能观察它的报文结构,上面的部分为请求,下面的部分为响应,也可以把他们放在文本中查看,下面是请求的报文格式:
下面来看响应的报文格式:
可以看到,不管是请求还是响应,都由首行、请求头、空行和正文四个部分组成。
2.3 认识URL
平时我们俗称的 "网址" 其实就是说的 URL (Uniform Resource Locator 统一资源定位符). 互联网上的每个文件都有一个唯一的URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它.
下面是URL中每部分的具体含义:
但是现在我们已经不通过URL来输入我们的登录认证信息了,因此这部分一般在现在的URL中是没有的,而且URL中有的部分也是可以省略的 。
而且协议方案名也并不只有http和https,如访问mysql时用的jdbc:mysql也是。
2.4 URL encode
像 / ? : 等这样的字符, 已经被url当做特殊意义理解了. 因此这些字符不能随意出现. 比如, 某个参数中需要带有这些特殊字符, 就必须先对特殊字符进行转义.
**转码规则:**将需要转码的字符转为16进制,然后从右到左,取4位(不足4位直接处理),每2位做 ⼀位,前⾯加上%,编码成%XY格式
1.在浏览器上搜索"哈哈"
其实中文也会被当作特殊字符进行转码的,只是在网页的URL中没有显示出来,但是使用抓包工具可以显示出来。
2.使用抓包工具查看URL
3.为什么需要转码?
由于URL中的Query String是程序员自定义的,如果在query string中输入了特殊字符如"?"(在URL中是用来区分query string的)就有可能导致对URL的解析出现错误(无法区分哪个?后面才是查询字符串)
2.5 认识 "方法"
请求方法有很多,最常用的就是get和post方法,一般情况下,get请求没有正文,而post请求有正文。
get和post方法的区别:
<1> 语义上:get 方法用于向服务器获取资源 ,post 方法用于向服务器发送资源
<2>携带数据的方式 :get一般通过query String携带 数据,post方法通过body携带数据
<3>GET 请求一般是幂等的, POST 请求一般是不幂等的 . (如果多次请求得到的结果⼀样, 就视为请求是幂等的).
<4>get可以被缓存,而post不能
但是现在对于get和post的用法并没有明确区别,两个都可以用来获取/发送资源,大部分的浏览器和服务器都是支持的。
2.6 Host
表示主机服务器的地址和端口号,一般和请求首行中URL中的地址和端口号一致
2.7 Content-Length
表示正文的长度(如果没有正文就没有)
主要是用来区分从哪里到哪里是一个完整的http请求
2.8 Content-Type
表示正文的类型(正文的类型有HTML、CSS、JS、JSON等)
2.9 User-Agen
包含浏览器和操作系统的信息
2.11 Referer
表示当前页面是由哪个页面跳转来的(如果是直接输入网址,不是跳转来的就没有这个信息)
如在搜狗页面输入哈哈,对跳转后的页面抓包:
2.12 Cookie
我们在网页中可能经常会涉及到用户登录,不知道大家在登录的过程中是否发现:只要你成功登录进一个网站后,在一段时间内再次访问这个网站时就不用再次登录了,这就是Cookie的作用
一、Cookie是什么?
cookie是服务器保存在客户端本地的一段数据,它是服务器发送给浏览器的小文本信息,浏览器会将它保存到本地(有时候访问网站可能会弹出询问你是否要保存Cookie的选项框,你也可以选择不保存)
通过抓包工具可以看到Cookie的信息:
也可以在浏览器中查看:
我们可以点击右键将当前Cookie删除,然后刷新页面并抓包,就可以观察到响应中的set-Cookie(用来将一些信息如sessionId等保存到浏览器的Cookie中)
二、session是什么?
Cookie经常和session联系在一起,session表示的是会话,比如我们在访问一个页面并登录的过程,就可以视为一次会话。在这个过程中,如果成功登录:
服务器就会生成一个session对象 (用来保存此次会话的关键信息 )并生成sessionId
然后将sessionId和session作为键值对保存到hash中
最后通过set-Cookie将sessionId返回给浏览器
三、Cookie的典型应用场景------登录和用户认证
2.13 状态码
1. 2xx(如200)
表示访问成功
2. 4xx (如404)
表示访问页面出错,表示的是客户端出现错误,通常是URL输入错误,也有可能是没有访问权限等。
3. 3xx (如302)
表示重定向(比如某个网址发生迁移,出现这状态码会自动跳转到服务器指定的另一个URL)
4. 5xx (如500)
表示服务器内部出现错误,如504表示服务器资源不足(在大学生进入选课网站是比较常见)
三、如何构造HTTP请求
对于后端程序员,常用的就是通过Postman来发送HTTP请求,如: