详解HTTP协议

目录

应用层协议

HTTP协议

HTTP协议的工作过程

HTTP协议格式

Fiddler的使用

抓包工具的原理

抓包结果

协议格式

HTTP请求(request)

请求报头 Header

请求正文body

HTTP响应

认识状态码

通过form表单构造HTTP请求

form表单发送GET请求

​编辑

form表单发送POST请求

通过ajax构造HTTP请求

通过JavaScript的ajax构造GET和POST请求


应用层协议

TCP\IP五层模型:

应用层 关注的数据传输到目标主机的目标端口之后,数据具体要如何使用

传输层 规定了数据从主机的那个端口发出,发给目标主机的那个端口

网络层 IP地址管理和路由的选择

数据链路层 Mac地址管理和同一个局域网内数据转发

物理层 规定了数据的传输介质

HTTP协议

HTTP:超文本传输协议,是一种非常广泛的应用层协议

HTTP是基于传输层的TCP协议实现的。

我们平时打开一个网站就是使用了HTTP协议来传输数据的。

HTTP的工作模式:一问一答的模式

当我们在浏览器中输入百度一下的URL时,浏览器就会给百度的服务器发送一个HTTP请求,百度的服务器也会给浏览器回复一个HTTP的响应。

当这个服务器给浏览器的响应被解析后,就展现成我们看到的页面内容,但是在这个过程中,一次请求和一次响应并不能传输这么多的数据,此时就需要多次请求和响应。也就说在这个过程中,浏览器会给服务器发送多个HTTP请求,而服务器则会给浏览器发送多个HTTP响应。这些响应就包含了页面HTML、Javascript、图片、文字等信息。

所谓超文本就是值传输的内容不仅仅是文本,HTML、CSS 这些就是文本,还可以是一些其他资源,比如图片、视频、音频等二进制数据。

HTTP协议的工作过程

当我们在浏览器中输入一个 "网址", 此时浏览器就会给对应的服务器发送一个 HTTP 请求. 对方服务器收到这个请求之后, 经过计算处理, 就会返回一个 HTTP 响应。

当我们访问这个网站的时候,当然不止一次的发送请求和响应。

我们可以同Chrome的开发者工具来看到这个详细的过程。

先进入百度的主页,然后按F12,再次刷新页面。然后点击网络。

HTTP协议格式

HTTP协议的格式我们使用fiddler抓包工具来研究。

Fiddler的使用

fiddler的下载 Fiddler | Web Debugging Proxy and Troubleshooting Solutions

左侧窗口显示了所有的 HTTP请求/响应, 可以选中某个请求查看详情. 右侧上方显示了 HTTP 请求的报文内容. (切换到 Raw 标签页可以看到详细的数据格式) 右侧下方显示了 HTTP 响应的报文内容. (切换到 Raw 标签页可以看到详细的数据格式) 请求和响应的详细数据, 可以通过右下角的 View in Notepad 通过记事本打开.

抓包工具的原理

抓包工具相当于一个代理。

所谓代理就是当浏览器访问百度的时候,会先把请求数据包都发送给Fidler,Fiddler在把请求数据转发给百度的服务器。

当 百度服务器返回数据时, Fiddler 拿到返回数据, 再把数据交给浏览器.。

抓包结果

下面是一个HTTP的请求和响应的转包结果

请求:

一个请求主要包含了4个部分:

首行:

方法[GET] + URL[https://edu.bitejiuyeke.com/tms/tms-homework-record/unlook] + 版本 [HTTP/1.1]。

Header: Header: 请求的属性, 冒号分割的键值对;每组属性之间使用\n分隔;遇到空行表示Header部分结束。

空行: 因为 HTTP 协议并没有规定报头部分的键值对有多少个. 空行就相当于是 "报头的结束标记", 或者 是 "报头和正文之间的分隔符"。

body: 空行后面的内容都是Body. Body允许为空字符串. 如果Body存在, 则在Header中会有一个Content-Length属性来标识Body的长度; 如果服务器返回了一个html页面, 那么html页面内容就是在body中. 。

响应:

首行: [版本号] + [状态码] + [状态码解释]

Header: 请求的属性, 冒号分割的键值对;每组属性之间使用\n分隔;遇到空行表示Header部分结束

空行:因为 HTTP 协议并没有规定报头部分的键值对有多少个. 空行就相当于是 "报头的结束标记", 或者 是 "报头和正文之间的分隔符"。

Body: 空行后面的内容都是Body. Body允许为空字符串. 如果Body存在, 则在Header中会有 一个Content-Length属性来标识Body的长度; 如果服务器返回了一个html页面, 那么html页 面内容就是在body中.

协议格式

为什么 HTTP 报文中要存在 "空行"? 因为 HTTP 协议并没有规定报头部分的键值对有多少个. 空行就相当于是 "报头的结束标记", 或者是 "报头和正文之间的分隔符". HTTP 在传输层依赖 TCP 协议, TCP 是面向字节流的. 如果没有这个空行, 就会出现 "粘包问题".

HTTP请求(request)

URL:

URL的基本格式

URL:统一资源定位符。也就是我们平时上的网站。

互联网上每一个文件都有唯一的URL,它包含的信息指出文件的位置以及浏览器怎样的处理它。

一个具体的URL:

 https://edu.bitejiuyeke.com/homework/recordList

https:协议的方案名,常见的有http和HTTPS两种类型的,当然也有其他类型的,比如jdbc:mysql。

user:pass 登录的信息,由于现在的网站不在通过url来进行身份认证了,所以就省略了。

edu.bitejiuyeke.com : 服务器的地址,此处是一个域名,域名会通过DNS来映射一个唯一的IP地址。

端口号:上面URL中的端口号被省略了,如果省略了,则会使用对应协议的默认端口,如http的默认端口是80,HTTPS的默认端口为443.

homework/recordList :带层次的文件路径。

后面是一些键值对,这里也省略了。键值对也叫查询字符串。主要作用就是对请求的资源进行细节上补充。

片段标识符:主要用于页面内跳转。

方法

HTTP中同样也有很多的方法。

我们只介绍GET方法和POST方法两种方法即可。

GET方法:

get方法是最常用的http方法,常用于获取服务器上的某个资源。

我们通过抓包工具就能看到GET方法的使用:

GET https://www.baidu.com/?tn=51076811_1_dg HTTP/1.1

当前我们抓的是访问百度的数据包。

开头的GET就是http方法,主要是描述了这个请求主要是获取百度的主页。

GET的语义就是从服务器哪里拿东西。

GET方法的特点

  • 首行的第一部分为GET

  • URL的query String部分可以为空,也可以不为空。

  • Header 部分有若干个键值对。

  • body部分为空。

关于GET请求的URL的长度问题?

实际上对URL的长度没有限制。

实际URL的长度取决于浏览器的实现和服务器的端的实现。在浏览器端,不同的浏览器支持的URL的长度不同,但是现在的浏览器一般URL的长度都很长,在服务器端,这个长度是可以配置的。

POST方法:

POST的语义就是往服务器里面提交个东西。

POST方法也是比较常用的一个方法,多用于提交用户输入的数据给服务器。例如登录页面。

我们可以登录一个网站来具体的看看post方法。

这是我们登录一个网站的数据包,是浏览器给服务器发送的请求包。

可以看到上面的POST方法。

POST方法的特点

  • 首行的第一部分一般为POST

  • URL中的query String 一般为空(当然也可以不为空)

  • Header 部分有若干个键值对

  • body部分一般为空,body 内的数据格式通过 header 中的 Content-Type 指定. body 的长度由header 中的 Content-Length 指定

GET方法和POST方法的区别

其实本质上来说,这两中方法并没有本质的区别。

使用GET的场景可以替换成POST,使用POST的场景,也可以替换成GET

但是在使用习惯上有区别:

  • GET常用于获取一个数据,POST则用来提交一个数据。

  • GET一般没有body,需要携带的数据则放在url中,POST一般有body。

  • GET则会通常设置为幂等的,而POST则无要求。

  • GET是可缓存的,POST则不能。

  • GET可以被浏览器收藏,POST则不能。

注意:GET和POST都没有长度的要求。

请求报头 Header

Header的整体结构也是键值对的结构,一个键值对占一行,键和值之间使用冒号 :做分割。

这里的键值对可以有N行,使用空行作为结束标志。

Header中的键值对,大多是都是使用HTTP协议规定的,当然我们可以自定义键值对。

HOST

Host: edu.bitejiuyeke.com

这个属性,描述了浏览器要访问的服务器是那个。

可以发现,这个HOST中的URL和首行中的URL是一致的。

这是因为如果当前我们访问网页不是直接访问的,而是通过代理的方式访问的。那么首行的中URL就是代理服务器的URL,而HOST中的URL就是最终的目标。

Content-Type、Conten-Length

这个属性是和body有关系的。

如果是一个没有body的GET请求,则在Header中也就没有这两个属性。

Conten-Length : 表示body中的数据长度。

Content-Type : 表示body中数据的类型。

User-Agent (UA)

用来标识用户使用的客户端是咋样的设备。

User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36

表示我这里用的windows10,使用的浏览器是chrome。

UA现在的一个重要的作用就是区分这个网页是使用什么设置打开的 (手机/平板/电脑)

Referer

表示这个页面是从哪个页面跳转过来的

Referer: https:www.bing.com

表示这个页面是从bing跳转过来的。

如果直接在浏览器中输入URL, 或者直接通过收藏夹访问页面时是没有 Referer 的。

Cookie是浏览器本身存储数据的机制。

Cookie: x-ms-gateway-slice=estsfd; stsservicecookie=estsfd; AADSSO=NA|NoExtension; buid=0.AT0AMe_N-B6jSkuT5F9XHpElWnmtoZ62_ZpPi8MrcPluNMcBAAA.AQABAAEAAAD--DLA3VO7QrddgJg7WevrjIPuyQ7JngJCL4KKoxJdbYMbmClufre9UU_DUcgpD-mWhbAvpWttdf-izMs2TQ-qgJEDNYO6YzpQnUEfVu8gTYE7L_uOluyg2nkYeiiNsSEgAA; fpc=AlBAIpK_lIpLuvT6d9uBaS9JSDCsAQAAAGSD9tsOAAAA; esctx=PAQABAAEAAAD--DLA3VO7QrddgJg7Wevr5rJnN5hRY-RxsoyGNiO1JSsCw5zrcu0-MwuU0rlIG6xyV2rJihEKfDUSCtqHwM-_QtiHPJyrvCvhc7J60rKBoETlr2ExoBMXFpLoSRDAtXurGGhXjtDNMTsRf9Z6NhDRp5zx1XL8wl2M20NqtpGsTU3GWs--frFjyWWi2krpkHcgAA

可以看出Cookie 本质上存储的也是键值对结构。

键值对之间用;分割

键和值之间用:分割

Conkie的本质就是浏览器在本地存储用户自定义数据的一种关键机制。

但是浏览器是不会存储在用户的硬盘上的。为了上网安全,浏览器会禁止网页直接访问硬盘。

浏览器虽然禁止了网页直接访问硬盘,但是浏览器提供了Cookie机制。允许网页往浏览器这边存储自定义的键值对,这些数据通过浏览器提供的特定的API,写入特定的文件中去。

由于网页是有很多的,访问不同的网页都会存储一些信息,针对这种情况,采用的做法是分开存储不同网站的Cookie(Cookie是按照域名为维度存储的)。

用一个网站,比如搜狗的主页,和搜索结果页,搜狗图片和搜狗知道......都是共享一份Cookie的。

不同的网站则是不同的Cookie。

1、Cookie从哪里来

Cookie从服务器上来,当我们浏览器访问服务器的时候,服务器就会在HTTP响应中通过set-cookie字段把Cookie的键值对返回给浏览器。浏览器收到这个数据后,就会在本地保存。

2、Cookie到哪里去

Cookie会在下次请求的时候,把Cookie带给服务器,Cookie在浏览器这边只能算是暂存。真正让这个数据发生作用,还得是服务器来使用。

3、Cookie有啥用

是浏览器本地存储数据的机制。

Cookie最典型的应用,就是存储用户的身份信息。

​上述的令牌就是Cookie。

请求正文body

请求正文一般是一个HTML,JS,CSS,图片等。

请求报头里面有两个字段和body密切相关,分别是

Content-Type:描述了正文的类型

Content-Length:描述了正文的长度

HTTP响应

认识状态码

状态码在HTTP的响应的首行

HTTP/1.1 200 OK

200状态码是一组数字,用来表示当前HTTP请求是否成功,如果没有成功,则失败的原因是什么。

OK状态码的描述,通过一组单词描述这个状态码的意思。

HTTP中提供的状态码是非常多的。

上述的状态码是非常繁多的,但是我们不需要全部掌握。只需要掌握常用的几个就行。

200   OK   表示的请求成功。

404   Not Found    表示访问的资源不存在。

403   Forbidden 访问被拒绝 (没有权限)

500   Internal Server Error    服务器内部错误

504   Gateway Timeout     服务器访问超时

302   Move temporarily     临时重定向

301  MovedPermanently   永久重定向

重定向就是我们要访问就得地址,但是被引导到新的地址上。

状态码整体可以分为几大类:

 关于HTTP的响应其他内容和请求一致。

通过form表单构造HTTP请求

在浏览器中HTTP请求的方式可以直接通过在地址栏输入URL的方式来构造一个HTTP请求。

在HTML中,一些特殊的标签也会触发GET请求,比如:

  • link
  • script
  • img
  • a

form表单的构造HTTP请求的方式:

form 的重要参数:
action: 构造的 HTTP 请求的 URL 是什么.
method: 构造的 HTTP 请求的 方法 是 GET 还是 POST (form 只支持 GET 和 POST)。

form表单发送GET请求

<!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="https://www.baidu.com/abc/def" method="get">
        <input type="text" name="aaa">
        <input type="text" name="bbb">
        <input type="submit" value="提交">

    </form>
</body>
</html>

可以看出我们通过form表单的方式成功的构造出来了一个HTTP请求。

 GET https://www.baidu.com/abc/def?aaa=111&bbb=222 HTTP/1.1

上述就是我们构造出来的HTTP请求的首行。

  • form 的 action 属性对应 HTTP 请求的 URL
  • form 的 method 属性对应 HTTP 请求的方法
  • input 的 name 属性对应 query string 的 key
  • input 的 内容 对应 query string 的 value
     

form表单发送POST请求

<!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="https://www.baidu.com/abc/def" method="post">
        <input type="text" name="aaa">
        <input type="text" name="bbb">
        <input type="submit" value="提交">

    </form>
</body>
</html>

 可以看到,代码整体不动,只是把method中的GET修改为post。

主要的区别:
method 从 GET 变成了 POST
数据从 query string 移动到了 body 中。

通过ajax构造HTTP请求

除了浏览器地址栏能构造 GET 请求, form 表单能构造 GET 和 POST 之外, 还可以通过 ajax的方式来构造 HTTP 请求. 并且功能更强大。

我们使用jQuery里面提供的API来构造。

通过JavaScript的ajax构造GET和POST请求

<!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>
    <script src="https://code.jquery.com/jquery-3.7.0.min.js"></script>
</head>
<body>
    
    <script>
        $.ajax({
            url: "https://www.baidu.com",
            type: "get",
            success: function(body) {
                console.log(body);
            }
        });
    </script>
</body>
</html>
  • 上述的URL表示向那个网站发送请求
  • type表示方法是什么
  • body则是响应的正文

但是需要注意的时,这个function不会在请求后立即执行,而是通过异步的方式来执行的。

也就是说,当我们把请求发送出去之后,只有服务器返回响应的时候,这个function才会执行。

如果需要构造POST请求,只需要把type中get换为post即可。

也支持HTTP中的其他方法,这是form表单做不到的。

相比之下,Ajax比form表单的方式更加灵活。

  • 10
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值