HTTP协议
1.HTTP是什么?
http是一种应用非常广泛的应用层协议,http协议是基于传输层的TCP协议实现的,我们平时打开一个网站,就是通过HTTP协议来传输数据的.HTTP也称为"超文本传输协议",不仅能传输字符串,而且能够传输图片,视频,音频等.
当我们在浏览器中输入一个 搜狗搜索的 “网址” (URL) 时, 浏览器就给搜狗的服务器发送了一个 HTTP 请求, 搜狗的服务器返回了一个 HTTP响应.
响应结果被浏览器解析之后,就能够展示成我们看到的页面(这个过程中浏览器可能会给服务器发送多个HTTP请求,服务器会对应多个响应,响应里就包含了HTML,CSS,JavaScript,图片,字体等).
应用层协议是干什用的
数据从客户端进程经过路径选择跨网络传送到服务器进程,所做的功能仅仅是传输节点,只是把数据传输给对端,而两端还要对数据进行加工处理或使用,所以我们还需要一个协议,就是应用层协议.举个例子:比如在在京东上买了一部手机,我们向商家发送了一个请求,商家会选择合适路径把物品发送给我,而手机中附带使用说明书,指导用户该如何使用手机,此时说明书就可以理解为用户层协议
当我们在浏览器中输入一个"网址",浏览器就会给对应的服务器发送一个HTTP请求,对方服务器浏览器收到这个请求之后,经过计算处理就会返回一个HTTP响应
当我们访问一个网站的时候,可能涉及到的HTTP请求/响应的交互过程不止一次.
2.HTTP协议格式
HTTP是一个文本格式的协议,可以通过一些工具来抓包,分析HTTP请求/响应细节.
此处以Fiddler为例,下载链接:https://www.telerik.com/fiddler/
左侧窗口显示了所有的HTTP请求/响应.
右侧上方显示了所有HTTP请求的报文内容(切换到Raw标签页可以看到详细的格式数据)
右侧下方显示了所有HTTP响应的报文内容(切换到Raw标签页可以看到详细的格式数据)
请求和响应的详细数据, 可以通过右下角的 View in Notepad 通过记事本打开.(查看响应报文时,需要解压缩)
使用ctrl+a可以全选左侧的抓包结果,delete键删除被选中的结果.
其实我们使用的抓包工具Fiddler相当于一个"代理".
浏览器访问Souhu.com时,会把请求先发给Fiddler,Fiddler在把请求转发给Sogou的服务器,当Sogou服务器返回数据时,Fiddler拿到返回数据,再把返回数据交给Fiddler.
此时Fiddler对于浏览器和Sogou浏览器之间的交互的数据是非常清楚的.
代理就可以简单理解为一个跑腿小弟. 你想买罐冰阔落, 又不想自己下楼去超市, 那么就可以把钱给你的跑腿小弟, 跑腿小弟来到超市把钱给超市老板, 再把冰阔落拿回来交到你手上. 这个过程中, 这个跑腿小弟对于 “你” 和 “超市老板” 之间的交易细节, 是非常清楚的.
以下下是搜狗的抓包结果:
HTTP请求:
- 行首:方法+URL+版本
- Header:请求的属性,冒号分隔的键值对;每组属性使用\n分割;遇到空行标识Header部分结束
- 主体(Body):空行后面的都是Body,Body允许为空字符串,如果Body存在,则会有Content-Length属性来标识body的长度.
HTTP响应:
- 行首:版本+状态码+状态码解释
- Header:请求的属性,冒号分隔的键值对;每组属性使用\n分割;遇到空行标识Header部分结束
- 主体(Body):空行后面的都是Body,Body允许为空字符串,如果Body存在,则会有Content-Length属性来标识body的长度.如果服务器返回了一个html页面,那么html页面内容就是在body中.
3.HTTP请求
3.1 URL
URL:唯一资源定位符,用来描述网络上的资源的,这里要明确描述出要访问的服务器是什么以及服务器的资源是什么.
一个完整的URL格式:
- 协议名方案:常见的http和https.
- 登录信息:一般不会再通过URL进行了,通常会省略
- 服务器地址:可以是一个ip地址,也可以是域名,可以是外网,内网,环回ip.
- 服务器端口号:用来区分应用程序.
- 带层次的文件路径:访问服务器的哪个资源.
查询字符串:访问资源的时候,带上什么样的参数,本质上是一个键值对结构,键值对之间使用&分割,键和值使用=分割.查询字符阿以?开始.
片段标识:主要用于页面跳转,通过不同的片段标识跳到不同的章节.
查询字符串(qurey string):内容是键值对,其中key和value的取值都是可以自己自定义的,可以通过这样的方式传输我们需要的信息给服务器.
URL中可以省略的部分:
- 协议名:省略后,默认为http://
- ip地址/域名:省略后相当于访问当前服务器的地址,比如访问访问某服务器的主页的html,那么html会触发一些其他的http请求,后续触发http请求,就可以省略ip,省略的ip就相当于和使用刚刚才获取服务器主页html一样的ip
- 端口号:当端口号省略的时候,浏览器会根据就协议类型自动决定使用哪个端口,比如http使用80端口,https协议使用443端口.
- 带层次的文件路径:相当于访问的就是/根目录,服务器提供的资源,类似于目录结构中的树形结构组织.通常根节点就会对应到服务器的主页.
- 查询字符串:可以省略,根据情况来处理
- 片段标识:可以省略.
关于 URL encode(转义编码)
qurey string中可能会带有一些特殊符号,而这些特殊符号,可能在url中本身具有一定的含义,就导致浏览器/服务器解析失败,其中包含:": / & = #"包括中文都需要转换.
转换规则:把要转换的内容的二进制的每个字节,都使用十六进制标识,在每个字节前面加上一个%.
3.2 方法
方法:描述的是"语义",要求这次要干什么.
-
GET方法:从服务器获取资源,比如在浏览器中输入一个URL,浏览器会发送出一个GET请求.GET把需要传递的数据通过query string传递,用户能够看到.body通常是空的.
GET请求的特点:1.行首的第一部分为GET.2.URL中的query string可以为空,也可以不为空.3.header有若干个键值对结构.4.body部分一般为空. -
POST方法:从服务器传输资源,常用于用户输入的数据提交给服务器.POST把传递的数据放到body中,用户不能看到.query string通常是空的.
POST特点:1.首行的第一部分为 POST.2.URL 的 query string 一般为空 (也可以不为空)3.header 部分有若干个键值对结构. body 部分一般不为空. 4.body 内的数据格式通过 header 中的Content-Type 指定. body的长度由header中的Content-Length 指定.
3.2.3 POST和GET的区别
- 1.语义不同:GET一般用于获取数据,POST用于提交数据
- 2.GET把需要传递的数据通过query string传递,用户能够看到.body通常是空的.POST把传递的数据放到body中,用户不能看到.query string通常是空的.
- 3.GET的请求一般是幂等的,POST请求一般是不幂等的(幂等:多次请求的得到的结果一样).
- 4.GET可以被缓存,POST不能被缓存.(前提是幂等的情况)
3.3 请求报头
header的整体是"键值对"结构,每个键值对占一行,键和之间使用分号分割.常见的种类有以下几个:
-
- HOST:表示服务主机的地址和端口,通常情况下Host里的内容和URL是一致的,但是也有例外,比如使用了代理等特殊情况.
-
- Content-Length:表示body中的数据长度,描述了body的长度是多少字节,body是从空行开始的,从空行开始到结尾就是body数据的长度.
通常这样设计是为了解决粘包问题,当浏览器连续给服务器发起多个HTTP请求的时候或者服务器连续返回多个HTTP响应的时候,浏览器就会通过:1.分割符 2.长度来区分一个完整的HTTP数据.如果是GET没有body就会通过空行来区分,是POST就会通过长度来区分.
- Content-Length:表示body中的数据长度,描述了body的长度是多少字节,body是从空行开始的,从空行开始到结尾就是body数据的长度.
-
- Content-Type:表示请求的body中的数据格式,在HTTP中主要有三种情况:
3.1. application/x-www-form-urlencoded:body的格式和query string一样,用于表单提交数据.
3.2. multipart/form-data:一般用于上传文件/图片
3.3.数据为json.数据格式为:{“username”:“xxxxxx”,“password”:xxx",“uuid”:“9f71c17e42e0409a83f799d921388f9e”,“status”:0}
- Content-Type:表示请求的body中的数据格式,在HTTP中主要有三种情况:
3.4 User-Agent(简述 UA)
User-Agent主要包含当前机器的系统和浏览器的版本.
3.5 Referer
描述了当前页面是从哪里获取的,如果通过浏览器直接输入URL或者点击收藏夹打开的网页,请求是不带referer,如果是点击了某个网站的内容,产生了跳转,就是携带referer的.
当点击了请求的页面的之后,就会跳转到对应的请求页面的网页,此时Referfer就是刚才的搜索结果页.
3.6 Cookie
Cookie是浏览器本地存储的一种机制.
在第一次浏览器访问服务器之间是没有任何与服务器相关联的数据的,此时用户在操作网页的时候,会产生很多"临时性"数据,有的数据存储在服务器,下次可以直接获取到,有的存放到浏览器存储,下次访问也可以直接使用,但是换一台设备就访问不了了,由于数据是存储在浏览器当中,很可能会被别人窃取或篡改,因此对比较重要的信息进行存储时我们需要进行加密处理.
Cookie是按照键值对的方式来存储一些字符串,这些键和值通过服务器返回,浏览器再把这些键值对按照"域名"维度分类存储,不同的网站cookie是独立的,cookie的内容都是可以通过自定义设置的.
一个网站中会有很多的键值对,此时会有一个很重要的键值对,用来表示用户的"身份信息".标识当前的请求是来自于哪个用户.这时候就需要使用Session机制.通过一个Session ID在客户端和服务器之间进行关联,就可以避免用户的敏感数据直接暴露.因为Session存储在服务器端,通过Session ID在客户端和服务器之间进行关联,通常我们在进行登陆的时候,服务器会为每个会话分配一个唯一的Session ID,与用户的状态相关联.Session的机制是通过Cookie来保存Session ID的.
4. HTTP响应
4.1 响应状态码
状态码 | 含义 |
---|---|
200 OK | 访问成功 |
404 Not Found | 没有找到资源 |
403 Forbidden | 访问被拒绝,没有权限 |
405 Method Not Allowed | 客户端使用了服务器不支持的方法(POST,GET等) |
500 Internal Server Error | 服务器内部出现错误 |
504 Gateway Timeout | 服务器处理单条请求的消耗时间过长,出现超时 |
302 Found | 请求的资源移动到不同的位置 |
301 Moved Permanently | 请求的资源永久性的移动到新的位置 |