目录
引言
HTTP是什么
HTTP(超文本传输协议)是一种应用非常广泛的应用层协议。应用层协议一般需要自定义协议,一方面也会用到一些现成的协议,HTTP协议就是最常用到的应用层协议。
一、HTTP协议概述
- HTTP协议全称为超文本传输协议,就是可以传输文本及其它格式的数据,如音乐、图片、视频等,是一种广泛应用的应用层协议;
- 对于应用层协议的解释: 将数据从A端传送到B端,TCP/IP协议相当于顺丰的功能,但是两端还要对数据进行加工处理或使用,所以还需要一层协议,不必关心通信的细节,只关心应用,这层协议就是应用层协议;
- 我们平时打开的网站都是通过HTTP协议来传输数据的,HTTP协议是基于传输层TCP协议实现(HTTP1.0,HTTP1.1,HTTP2.0都是基于TCP,HTTP3.0基于UDP实现),我们此处介绍HTTP1.1为主
- 如:在浏览器上输入百度的网址(URL)时,浏览器向百度服务器发送一个HTTP请求,百度的服务器给我们返回一个HTTP响应,响应被浏览器解析后,就展示为页面内容。
二、HTTP协议的工作过程
当我们在浏览器输入一个网址,此时浏览器就会给对应的服务器发送一个HTTP请求,对方的服务器收到这个请求之后,经过计算处理,就会返回一个HTTP响应。
事实上,当我们访问一个网站的时候,可能设计不止一次的HTTP请求/响应的交互过程。
三、HTTP协议格式
3.1 抓包工具的使用

- 左侧窗口显示了所有的HTTP请求/响应,可以选中某个请求查看详情;
- 右侧上方显示了HTTP请求的报文内容(切换到raw标签页可以看到详细的数据格式)
- 右侧下方显示了HTTP响应的报文内容(切换到raw标签页可以看到详细的数据格式)
- 请求和响应的详细数据,可以通过右下角的View in Notepad通过记事本打开
3.2 抓包工具的原理
Fiddler相当于一个代理。浏览器访问 sogou.com 时, 就会把 HTTP 请求先发给 Fiddler, Fiddler 再把请求转发给 sogou 的服务器. 当 sogou 服务器返回数据时, Fiddler 拿到返回数据, 再把数据交给浏览器. 因此 Fiddler 对于浏览器和 sogou 服务器之间交互的数据细节, 都是非常清楚的.
如:如:我想吃一碗粉,但是不想亲自过去,于是我点了一份外卖,对于我而言我没有与老板直接见面,而是通过外卖员来进行交互。
此时这个抓包工具(代理)就可以获取到浏览器和服务器之间的交互细节了,也就可以拿到HTTP请求和HTTP响应中的具体信息了。
HTTP请求:
HTTP响应:
3.2 协议格式总结
HTTP请求:
- 首行:请求方法+URL+协议版本号,这三个部分使用空格来分割;
- Header头:请求的属性,用冒号空格分割键值对,每个键值对独占一行
- 空行:表示Header头的结束
- Body:空行后面的内容都是Body,Body允许为空,如果Body存在,则在Header头中有一个Content-Length的属性来标识Body的长度
HTTP响应:
- 首行:协议版本号+响应状态码+状态码解释符
- Header头:请求的属性, 用冒号空格分割键值对,每个键值对独占一行
- 空行:表示Header头的结束
- Body:空行后面的内容都是Body,Body允许空,如果Body存在,则在Header头中有一个Content-Length的属性来标识Body的长度
思考问题: 为什么HTTP报文中要存在空行呢?
因为HTTP协议并没有规定抱头部分的键值对有多少个,空行就相当于报头的结束标志,或者是报头和正文之间的分隔符。
HTTP在传输层依赖TCP协议,TCP是面向字节流的,如果没有这个空行,就会出现粘包问题。
四、HTTP请求
4.1 URL的基本格式
4.1.1 认识URL
4.1.2 URL基本格式
4.2 关于URL encode
- 当 query string 中如果包含了特殊字符,就需要对特殊字符进行转义(url encode)
- 这个转义过程就叫做 url encode,反之,把转义后的内容还原回来就叫做 url decode
url 里面是有很多特殊含义符号的:/ : & = … 这些符号都是在 URL 中具有特定含义的~
注意:如果query string里包含了这类特殊符号,就可能导致URL被解析失败
如:当我们在百度中搜索C++的时候,就可以看到URL中的query string里面有一个键值对,就表示查询词内容。
4.3 认识请求方法
请求方法标识具体使用什么方式来操作资源,如:获取资源,保存资源,修改资源,删除资源,属于操作资源的类型。
此处讲解最常用的GET和POST方法,其它方法了解即可。
4.3.1 GET方法
GET是最常用的HTTP方法,常用于获取服务器上的某个资源,在浏览器直接输入URL,此时浏览器就会发送一个GET请求。后面会介绍到,使用JavaScript中的ajax也能构造GET请求。
GET请求的特点:
- 首行的方法为GET
- URL的queryString可以为空,也可以不为空,数据一般存放于queryString中
- body一般为空
4.3.2 POST方法
POST方法常用于将用户输入的数据提交到服务器(如登陆功能,上传图片),通过HTML中的form标签能构造POST请求,使用JavaScript中的ajax也能构造POST请求。
POST请求的特点:
- 首行的方法为POST
- URL的queryString一般为空
- body一般不为空,数据一般保存在body中
4.3.3 经典面试题:GET与POST的区别
1、语义不同
(1)GET:是从服务器获得数据,更多的是取数据的过程;
(2)POST:是向服务器提交/发送要被处理的数据,更多的是用来上传数据
但现在GET也经常用来上传数据,POST也用来取数据
2、GET的body一般为空,需要传递的数据通过query string传递,POST的quert string一般为空,需要传递的数据通过body传递
3、GET请求一般是幂等的,POST请求一般是不幂等的(如果多次请求的结果一样,就视为请求是幂等的)
4、GET可以被缓存,POST不能被缓存。
能不能缓存是与是否幂等相关联的,因为幂等的结果是相同的,这样记录就提高了效率,不用重新查找,而非幂等结果本身就是不确定的,因此也没有必要被缓存而浪费时间。
5、关于传输数据量
有资料说GET传输的数据小,POST传输的数据大,这个不是科学的,标准没有规定GET的URL的长度,也没有规定POST的body的长度,传输数据量多少,完全取决于不同浏览器和不同服务器之间的实现区别。
6、安全性不同
GET是把参数直接显示在URL上,不安全,POST是放在body中,相对安全,但也不完全就说POST比GET安全,因为用抓包工具就可以抓到POST请求正文中的数据,是否安全取决于对数据进行加密。
4.3.4 请求报头
header的整体格式是键值对结构,每个键值对占一行,键与值之间是有冒号空格分隔。
注意:这与query string/body中的键值对不同,它们是程序员自定义的,header中的键值对,主要是标准规定的,也有可以自定义的部分。
1、Host :
表示服务器主机的地址和窗口。
可能会有疑问,Host里面的内容,不是在URL中已经有了嘛,为什么还要再重复一遍?
是因为Host里的内容和URL是一致的,但是也有例外,比如如果使用了代理,就不一定一样了!
2、Content-Lengtth:
表示body中的数据长度。
描述了body的长度是多少字节,如果请求有body,这个字段(Content-Lengtth)就必须有,否则就是非法的;如果没有body,这个字段就可以没有,body的字节是从空格开始数,数Content-Lengtth这么长,body就结束了。目的是为了解决粘包问题。
3、Content-Type:
表示请求的body中的数据格式。
针对这个数据,到底如何解析?如何理解?
HTTP协议有很多用途,传输的数据也有很多种类。
在HTTP请求中,Content-Type有三种主要的情况:
(1)application/x-www-form-urlencoded: form 表单提交的数据格式,body的格式就和quert string格式一样
(2)multipart/form-data: form 表单提交的数据格式(在 form 标签中加enctyped="multipart/form-data" . 通常用于提交图片/文件
(3)application/json: 数据为 json 格式
4.4 User-Agent(UA)
UA的作用:
互联网早期的时候,网站主要就是文字,但随着浏览器不断更新,支持的功能越来越丰富,就导致了新的浏览器支持的功能更多,旧的浏览器支持的功能更少,同一时刻,市面上有人使用的是新浏览器,有人使用的是就浏览器,因此就有了UA,浏览器在发起HTTP请求的时候,向服务器自报家门,告诉服务器,使用的啥系统,啥浏览器上网的,服务器就根据这个信息来区分,主要是解决兼容问题。
但是目前UA的意义小了很多,主要用来区分PC端还是移动端。
4.5 Refer
描述了当前页面从哪里来
如果是通过浏览器地址直接输入URL/点击收藏夹来打开网页,这个请求就是不带Refer;
如果是点击某个网页的内容,产生了跳转,就是带Refer。
4.6 Cookie
是浏览器本地存储数据的机制。
1、什么是Cookie?
Cookie就是给浏览器提供一种能够持久化存储数据的机制。这里的持久化是指不会因为电脑或者应用程序重启而导致数据丢失,也就是说实质上是写在磁盘上的内容。
2、Cookie的组织形式:
a.根据域名来组织,针对每个域名分配一个小房间。
举个例子,当我访问百度的时候,浏览器会给这个域名记录一组cookie
b.在其中一个小房间里,又会按照键值对的形式来组织数据。
如:
3、Cookie数据来源:
Cookie数据实际上服务器返回给客户端的
4、如何更好的理解Cookie?
这里举一个通俗易懂的例子:
当你去一个医院看病的时候,往往那个医院会让你去办一张就诊卡,后续的所有操作都是基于就诊卡上来进行的操作,这个就诊卡就有唯一确定你身份的身份证号码和名字。因此当你后续需要再次来该医院看病时,医生一刷你的就诊卡就能够知道你的既往病史,若是医生给你开了检查或者是药,那么这个时候就存储在了你的就诊卡上。此时cookie就相当于这个就诊卡,但是它存储的大小也是有限的,因此实际上存储我信息的并不是这张卡,而是可以由这张卡连接的医院的服务器。服务器通过这张卡作为媒介来存储需要的信息。
Cookie的最重要的应用场景就是存储会话id,进一步的让访问服务器的后续页面的时候。能够带上这个id 从而让服务器能够知道当前的用户信息.(服务器上保存用户信息这样的机制就称为Session会话)。
如同这里,每个session上存储了用户的关键信息(基本信息,既往病史......)每个session也有一个会话标识sessionld(这里就诊卡的sessionld就是指存储这个会话的id)
那么cookie能不能存别的信息?
答案是可以的,这个是可以根据程序员的需要来进行设定的。
⑤对session会话的理解:
我们可以把微信列表的所有聊天对象作为会话,那么每一个对象中的详细内容就是该会话的详细信息
五、HTTP响应解析
5.1 状态码
状态码:就是对这次响应的定性(响应的结果是成功了,失败还是其它的情况)
常见状态码:
- 200:表示服务器对当次请求处理成功
- 404 Not Found:找不到请求路径URL对应的资源
- 304 Not Modified:表示之前访问过的资源,本次请求时没有被修改过,也就是客户端直接从缓存中获取
- 403 Forbidden:表示访问被拒绝,一般是没有访问权限,没有登陆时就访问就会出现403
- 405 Method Not Allowed:方法不支持,检查前端请求方法也要检查后端的请求方法
- 500 Internal Server Error:服务器内部错误,要检查后端控制台异常堆栈信息
- 504 Gateway Timeout:请求在服务端处理超时,服务端也有返回响应的时间限制,发现处理时间超时就返回504
- 302 Move temporarily:临时重定向,响应报文的header部分会包含一个Location字段,表示要跳转到哪个页面
- 301 Moved Permanently:永久重定向,301也是通过Location字段来表示要重定向到的新地址
5.2 响应报头(Header)
响应报头的格式与请求报头的格式基本一致,也就是Content-Type,Content-Length等属性含义也和请求中含义相同 ,响应请求头中可能会有Location属性,指重定向跳转的路径
响应中的Content-Type常见取值有以下几种:(body中的数据格式)
- text/html:body数据格式是HTML
- text/css:body数据格式是CSS
- text/javascript : body数据格式是JavaScript
- application/json:body数据格式是JSON
六、构造HTTP请求
6.1 通过 form 表单构造 HTTP 请求
6.1.1 form发送GET请求
form的重要参数:
1、action:构造的HTTP请求的URL是什么
2、method:构造的HTTP请求的方法是GET还是POST(form只支持GET和POST)
input的重要参数:
1、type: 表示输入框的类型. text 表示文本, password 表示密码, submit 表示提交按钮.
2、name: 表示构造出的 HTTP 请求的 query string 的 key. query string 的 value 就是输入框的用户输入的内容.
3、value: input 标签的值. 对于 type 为 submit 类型来说, value 就对应了按钮上显示的文本.
<form action="http://abcdef.com/myPath" method="GET">
<input type="text" name="userId">
<input type="text" name="classId">
<input type="submit" value="提交">
</form>
6.1.2 form发送POST请求
与构造GET请求不同的是只需将form的method由GET修改为POST
<body>
<!-- form表单,action为请求的url,method为请求的方法 -->
<form action="https://www.sogou.com/" method="POST">
<!-- name作为键,内容作为值,多个键值对用&间隔 -->
<input type="text" name="username">
<Input type="password" name="password">
<input type="submit" value="提交">
</form>
红色框里面的内容就是给服务器提供的内容。
6.2 Ajax构造HTTP请求
①为什么要引入基于ajax来实现:
因为如我们上面可知,form表单这种形式是一个比较原始的方式,使用form就一定会涉及到页面跳转,这个时候就需要加载浏览器的全部页面,很显然,这是非常麻烦的,尤其是当本身牵扯到的页面较多的时候。所以我们就想能不能只对局部进行变化。而这个情况,就可以用ajax了。
②什么是ajax:
ajax 全称为 Asynchronous(异步) Javascript And XML,是 2005 年提出的一种 JavaScript给服务器发送HTTP 请求的方式。
而实现ajax主要是基于js代码,构造出HTTP请求,再通过js代码来处理响应,并且把一些数据更新到页面上。
③理解异步(举例):
我去找朋友玩,但是他还在上班,我一直在等他,有两种等法,一个是我在他公司门口一直等,啥事也不干,这就是同步,还有一个等法是我在等他下班之前我先干别的事情去了,等他下班了来找我,这就是异步。
④同步和异步的区别:
同步是等待的责任放到发起者身上,异步是等待的职责放在被发起者的身上。
⑤ajax基于异步等待是如何进行的?
ajax就是一种异步的通信方式,通过代码发出http请求,请求发出去之后,JS代码就继续往下执行了,当服务器的响应回来之后,就会自动的通知咱们的代码,进一步就能处理响应了。