一,什么是HTTP
HTTP(全称为“超文本传输协议”)',是一种应用非常广泛的应用层协议,之前在《初识网络原理》的博客(初识网络原理_徐憨憨!的博客-CSDN博客)中,有详细讲解过TCP/IP五层模型,其中应用层描述了数据的传输,负责应用程序间的沟通。
HTTP作为一个应用层协议,同样需要通过封装和分用来进行交互,HTTP往往是基于传输层的TCP协议实现的,实现了浏览器和服务器之间的交互;例如当我们在浏览器中输入一个百度的网址(URL)时,浏览器就会给百度服务器发送一个HTTP请求,百度的服务器就会给浏览器返回一个HTTP响应:
这个响应被浏览器解析之后,就展示成我们看到的页面内容,这个过程中,浏览器可能给服务器发送了多个请求,服务器对应的也会返回多个响应,这些响应里就包含了页面HTML,CSS,JavaScript,图片,文字等。
二,HTTP 的工作过程
1.工作过程
核心:浏览器给服务器发送请求,服务器响应浏览器的请求,HTTP就是浏览器和服务器之间交互的桥梁
2.抓包
现在我们大致知道了HTTP通过发送请求,然后服务器响应请求这样的过程来进行交互的,同时当我们访问一个网站时,可能涉及不止一次的请求/响应的过程,那如何知道http协议交互的详细过程呢?此时就需要借助第三方工具(称为“抓包”工具:fiddler)来看到。
1.fiddler的下载和使用
进入fiddler下载的官网进行下载安装(https://www.telerik.com/fiddler/)
打开fiddler,安装https证书(因为大部分的hhtp协议都加密成了https)
3.选取一个抓取的包查看请求和响应
2.抓包工具的原理
Fidler相当于一个“代理”,当浏览器输入百度的网址进行访问时,就会先把请求发送给Fiddler,Fiddler再把请求转发给百度的服务器,当百度的服务器拿到数据返回时,Fiddler先拿到返回数据,再把数据交给浏览器,所以Fiddler可以清楚的知道浏览器和防服务器之间交互的数据细节。
三,HTTP协议格式
1.HTTP请求:
首行:【方法】+【URL】+【版本】;
Header:请求的属性,冒号分割的键值对;每组属性之间使用\n分隔;遇到空行表示Header部分结束;
Body:空行后面的内容是Body,Body允许空字符串,如果Body存在,则在Header中会有一个Content-Length属性来表示Body的长度。
2.HTTP响应:
首行:【版本号】+【状态码】+【状态码解释】;
Header:请求的属性,冒号分割的键值对;每组属性之间使用\n分隔;遇到空行表示Header部分结束;
Body:空行后面的内容是Body,Body允许空字符串,如果Body存在,则在Header中会有一个Content-Length属性来表示Body的长度,如果服务器返回了一个HTML页面,那么HTML页面内容就是在Body中。
3.格式图片总结
思考:为什么HTTP报文中要存在“空行”?
因为HTTP协议并没有规定报头部分的键值对有多少个,空行就相当于是“报头的结束标记”,或者是“报头和正文之间的分隔符”,HTTP在传输层依赖TCP协议,TCP是面向字节流的,如果没有这个空行,就会出现“粘包问题”。
四,HTTP请求
1.URL基本格式
URL(统一资源定位符)就是平时俗称的“网址”,互联网上的每一个文件都有一个唯一的URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它。
假设一个网址如下:
https://v.bitedu.vip/personInf/student?userId=10000&classId=100
https:协议方案名;常见的有http和https,也有其他的类型(例如访问mysql时用的jdbc:mysql);
user:pass:登录信息;现在的网站进行身份认证一般不再通过URL进行了,一般都会省略;
v.bitedu.vip:服务器地址;此处是一个“域名”,域名会通过DNS系统解析成一个具体的IP地址;
端口号:上面的URL中端口号被省略了,当端口号省略的时候,浏览器会根据协议类型自动决定使用哪个端口;例如http协议默认使用80端口,https协议默认使用443端口;
/personInf/student:带层次的文件路径;
userId=10000&classId=100:查询字符串(query string);本质是一个键值对,键值对之间使用&分隔,键和值之间使用=分隔;
片段标识:此URL中省略了片段标识,片段标识主要用于页面跳转。
注意:
query string中的内容是键值对结构,其中key和value的取值和个数,完全都是程序员自己约定的,可以通过这样的方式来自定制传输信息给服务器
URL中可以省略的部分:
协议名:可以省略,省略后默认为http://
ip地址/域名:在HTML中可以省略(比如img,link,script等),省略后表示服务器的ip/域名与
当前HTML所属的ip/域名一致
端口号:可以省略;省略后如果是http协议默认使用80端口,https协议默认使用443端口;
带层次的路径:可以省略;省略后相当于/,有些服务器会在发现/路径的时候自动访问/index.html;
查询字符串:可以省略;
片段标识:可以省略。
2.方法
GET方法
get方法是最常用的http方法,常用于获取服务器上的某个资源
触发GET请求的方法:
在浏览器中直接输入URL,此时浏览器就会发送出一个GET请求;
HTML中的link,img,script等标签,也会触发GET请求;
JavaScript中的ajax也能构造GET方法。
GET请求的特点:
首行的第一部分为GET;
URL的query string可以为空,也可以不为空;
hearder部分有若干个键值对结构;
body部分为空。
POST方法
POST方法也是一种常见的方法,多用于用户提交用户数据给服务器(例如登录页面)
触发POST请求的方法:
HTML的form标签可以构造POST请求;
JavaScript中的ajax也可以构造POST请求。
POST请求的特点:
首行的第一部分为POST;
URL的query string一般为空(也可以不为空);
hearder部分有若干个键值对结构;
body部分一般不为空,body内的数据格式通过header中的Content-type指定,body的长度由header中的Content-Length指定。
面试题:GET和POST的区别
核心:本质没有什么区别,只是使用习惯上的区别
语义不同:GET一般用于获取数据,POST一般用于提交数据;
GET的body一般为空,需要传递的数据通过query string传递,POST的query string一般为空,需要传递的数据通过body传递;
GET请求一般是幂等的,POST请求一般是不幂等的(如果多次请求得到的结果一样,就视为幂等);
GET可以被缓存,POST不能被缓存。
3.请求报头(Header)
header的整体格式是键值对结构,每个键值对占一行,键和值之间使用分号分割
HOST:表示服务器主机的地址和端口
Content-Length:表示body中的数据长度
Content-type:表示请求中的数据格式
User-Agent(UA):表示浏览器/操作系统的属性
Referer:表示这个页面是从哪个页面跳转过来的
Cookie:Cookie 中存储了一个字符串,这个数据可能是客户端(网页)自行通过 JS 写入的, 也可能来自于服务器(服务器在 HTTP 响应的 header 中通过 Set-Cookie 字段给浏览器返回数据);往往可以通过这个字段实现 "身份标识" 的功能;每个不同域名下都可以有不同的Cookie,不同网站之间的Cookie并不冲突
五,HTTP响应
1.状态码
状态码表示访问一个页面的结果(是访问成功,还是失败,还是一些其他的情况......)
常见状态码:
200 OK:表示访问成功
404 Not Found:表示没有找到资源
403 Forbidden:表示访问被拒绝,有的页面通常需要用户具有一定 的权限才能访问
500 Internal Server Error:表示服务器内部出现错误
504 Gateway Timeout:表示当前服务器负载比较大,服务器处理单条请求的时候消耗的时间就会很长,就可能导致出现超时的情况
302 Move temporarily:临时重定向
301 Moved Peramnently:永久重定向
2.响应报头
响应报头的基本格式和请求报头的格式基本一致
六,构造HTTP请求
利用form表单构造请求
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!-- -->
<form action="http://www.sougou.com" method="get">
<input type="text" name="studentName">
<!-- input type=submit 构造了一个特殊的 提交 按钮 value属性描述了按钮中的文本 -->
<!-- 点击这个按钮就会触发该 form 表单的"提交操作" 也就是构造http请求发送给服务器 -->
<input type="submit" value="提交">
</form>
</body>
</html>
利用ajax构造请求
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!-- 引入 jquery -->
<script src="https://lib.baomitu.com/jquery/3.6.3/jquery.min.js"></script>
<script>
$.ajax({
type: 'get',
url: 'https://www.sougou.com?studentName=zhangsan',
//此处success就声明了一个回调函数,就会在服务器响应返回到浏览器的时候触发该回调
//正是此处的回调体现了 "异步"
success: function(data) {
//data是响应的正文部分
console.log("当服务器返回的响应到大浏览器之后,触发该回调");
}
});
console.log("浏览器立即往下执行后续代码");
</script>
</body>
</html>