本文主要介绍了Http协议的作用以及如何通过抓包工具Fiddler抓取http请求/响应,重点介绍了请求/响应报文的内容
一.Http协议
最常用的应用层协议
http超文本传输协议,除了能传输字符串文本,还能那个传输其他的
比如:
浏览器打开网站这个过程都是http支持的;使用app,加载数据,这个过程也是http支持的
https本质还是http,是进化版本!
>http请求
>http响应
我们在浏览器看到的网页其实是我们在向服务器发送一个http请求,然后服务器会给我们返回一个http响应(通常是html/css/js),在浏览器显示,这就是我们看到的网页。
二.抓包工具Fiddler
学习http需要学习协议格式,需要用到 抓包工具(本质是代理)
抓包工具相当于是服务器和浏览器之间的一种代理,通过抓包工具就可以获取到浏览器和服务器之间的交互细节,也就可以拿到http请求和http响应中的具体信息
抓包工具是一种代理
但是代理不一定都是抓包工具,还有一些其他的。
正向代理:代理客户端
反向代理:代理服务器
抓包工具有很多:
比如wireshark,功能强大,但是使用比较复杂;这里使用fiddler,虽功能更少,但是使用很方便,也足够用
下载:Fiddler官网下载经典版(免费)
打开之后的样子:
左侧显示当前机器上有哪些http数据报在交互(不仅能抓浏览器的,而且能抓到所有程序的)
注意:刚装Fiddler的时候,是抓取不到https的,要抓https要稍微设置一下
举个例子:
我们现在在浏览器访问了搜索浏览器的主页面
>在Fiddler左侧就会显示一条这样的信息
>双击这条信息,右侧就会显示这条应用层数据报的https请求和响应
http请求报文(点击Raw看原生的)
可以用记事本打开查看(看的出来并不是乱码,这样意味着http协议是文本协议-->用记事本打开看得懂)
http响应报文
注意:响应通常会进行压缩(为了节省带宽),因此在查看之前要先进行解压
从http响应报文中也可以直观的看出来,它的内容大多数就是html/css/js
这也印证了那句话:访问网页的过程就是浏览器从服务器把数据下载下来的,然后在浏览器显示
三.请求报文和响应报文
1.请求报文
请求报文有四个部分:
1.首行
2.请求头header
3.空行
4.正文body
比如(通过Fiddler查看抓取到的一个请求报文)
1.1首行
//首行
GET https://www.sogou.com/web/css/yuyin.v1.0.1.css HTTP/1.1
首行组成:method方法 url http版本号
>URL唯一资源定位符
用来描述网络上的资源
请求就是客户端给服务器发起一个数据,在这里指出要访问的服务器以及服务器的资源是什么
RFC官方文档给出的url格式:
查询字符串query string:针对访问的资源进行补充说明
键值对格式,键值对之间使用&符号分割(键和值的含义都是程序员自定义的)
注意:url有些内容是可以省略的
比如,
省略IP地址相当于是访问当前服务器的地址;
省略端口号,浏览器会自动加上
(这个端口号表示的是访问目标服务器的哪个端口)
如果是http协议,自动添加80端口(http服务器端口号80)
如果是https,自动添加443端口(https服务器端口号是443)
因此一个商业服务器部署服务器的时候,往往会遵守上述规则:http协议绑定到80,https绑定到443端口
省略带层次路径:就相当于访问根目录/主页
正式上述灵活性,使http可以根据不同的场景,进行一些自定制的工作,也使得http成了
广泛使用的协议。
Urlcode
对url进行编码
例子:这个url中我们可以看到%还有一些类似于十六进制的数字,这就是url转码后的样子
https://cn.bing.com/images/search?view=detailV2&ccid=5or%2fQ%2fua
&id=798251EDFD497BC501D529226E9248C195C6E01D
为什么要转码?
这是因为有一些特殊字符(比如/!@#%等)会和url语法冲突,如果不转换,就可能导致浏览器/服务器解析失败;此时query string中就不会出现特殊含义的符号,浏览器和服务器才能正确识别。
转码规则:把要转换的内容的二进制的每个字节,都使用16进制表示出来,然后在每个字节
前面加上一个%
总结:url转码的作用是将特殊字符转义为了保证url的正确解析还有避免url语法冲突
>方法method
描述了这个请求是做啥的
上述方法用的最多的是前两个:
GET:从服务器获取***
POST:向服务器传输***
(实际上,现在GET/POST 不一定遵守之前设计的语义了)
>GET方法
一般没有正文(body) ,就像上面搜狗的http请求
>POST方法
一般有正文(body),空行分隔了header和body,相当于分隔符
body里的格式有很多种,也有键值对,只是经过了urlencode转码
常见场景:登陆/上传
比如这个请求:
经典面试题!!!
POST和GET的区别:
1.GET是把一些自定义的数据放在query string里,body通常是空的
2.POST是把一些自定义的数据放在body里,query string通常是空的
(不管放哪里都是要上传到服务器,本质没有区别)
放在url中,用户可以直接看到(浏览器收藏夹可以收藏);放在body中,无法直接看到;
实质上,GET和POST没有本质区别,两者经常可以相互替代
误区:
1.url长度有限制
RFC官方文档明确说明对url的长度不做限制
2.POST比GET更安全
POST只是把传输的数据让普通用户无法直接看到,但是不影响黑客截获;
保证安全的关键:对传输的的敏感数据进行加密!
3.GET是幂等的,POST不是幂等的
幂等:相同的出入,每次都是相同的输出;
不幂等:相同的输入,每次输出不幂等
RFC文档只是建议这样设计;实际开发中,不一定真的会这样设计
4.GET可以缓存,POST不能被缓存
(缓存的前提是幂等的)不管是GET和POST,幂等/不幂等都是不确定的,缓存自然也不能确定
其他方法
(稍微了解一下)
1.2请求头header
也是键值对结构,每一行是一个键值对
键和值之间使用 :空格来分割
方框里的字段是需要我们认识并了解的!
>Host
表示服务器主机的地址和端口
>Content_Length
表示body的数据长度;如果没有body,这个字段也可以省略
(为了解决粘包问题,区分每个完整的数据包)
粘包问题:
GET请求:使用空行作为结束符
POST请求:使用长度标识
>Content_Type
表示请求的body中的数据结构
主要有三种情况:
1)application/x-www-form-urlencoded
body的格式和query string一样
2)multipart/form-data
一般上传文件/图片
3)applicatin/json
body是json格式
>Referer
描述了当前页面的来源
*如果是从url/收藏夹中打开的网页,那么请求不带referer
*如果是点击某个网页的内容产生的跳转,就带上referer
问题:referer是明文传输的,因此有可能被修改,比如运营商就可以修改referer(运营商劫持)
解决方法:使用https进行加密传输
>Cookie
是浏览器本地存储数据的一种机制
用户访问网页的过程中,会产生很多临时性的数据
对于临时数据,有的可以放到服务器存储(下次就可以直接获取到)
有的不太重要的,就可以直接放到浏览器存储(下次访问可以直接用)
举个例子:
为了保证安全,浏览器会对网页的功能做限制(比如禁止直接访问硬盘),同时为了又能存储数据,浏览器就提供了Cookie功能
Cookie
* 按照键值对的方式存储一些字符串,这些键值对往往都是服务器返回回来的,浏览器把这些键值对按照域名维度,分类存储(不同的网络的cookie是独立的,里面的内容是自定义的)
当前网站涉及到两个域名,一个网站cookie中会存储很多键值对,其中往往会有一个很重要的键值对,用来表示用户的身份信息,标识当前请求来自哪个用户,这样登陆一个网站之后,后续再访问这个网站,就不必重新登陆。
为了实现身份识别的效果,不仅仅需要cookie来支持,在服务器也需要session机制
Session
首次访问网站,登陆成功之后,网站就会有一个sessionId,它会被服务器返回给浏览器的响应,保存在浏览器的Cookie中,服务器也会创建一个对应的Session,记录一些关键信息,服务器会用类似于hash表这样的方式,以sessionId为key,以session为value,把数组组织起来。
后续去访问网站的其他页面,都会在请求的Cookie字段中,带上sessionId,服务器就可以根据sessionId知道当前的用户信息
以上是网站登陆以及身份识别这样功能的实现的基本思路~
总结:
1.Cookie从哪里来
从服务器返回给浏览器的
2.Cookie保存在哪里
保存在浏览器上,浏览器所在电脑的硬盘上,每个域名都有自己的一组cookie
3.Cookie内容是什么
键值对结构的数据(程序员自定义的)
其中往往会有一个键值对,作为用户的身份标识
4.Cookie的内容到哪里去
后续再访问这个网站,就都会在请求中带上cookie,服务器就可以进一步的知道客户端的详细情况了。
1.3空行
作为header和body的分割
2.响应报文
响应报文也有四个部分:
1.首行
2.响应头header
3.空行
4.正文body
2.1首行
HTTP/1.1 200 OK
首行的组成:http版本号 状态码 OK
状态码是对这次响应的定性(成功/失败/其他情况)
一些常见的状态码:
200 OK成功
404 Not Found访问的资源不存在
403 Fobidden没有权限
502 Bad Gateway 服务器挂了
504 Gateway Timeout 服务器响应超时
302 Move temporarily重定向 浏览器会自动跳转到其他页面上
2.2响应头header
除了请求头中说到的host/content_length/content_type/referer/cookie等字段
响应头中可能还有这些
2.3空行
依旧是header和body的分割