文章目录
HTTP 协议是什么
HTTP 协议,全称是超文本传输协议,是应用最广泛的应用层协议。
应用层协议,不关注数据如何传输,关注的是数据传输过来后,如何去使用。
我们在浏览器中访问网站,浏览器就会发送 HTTP 请求 给对应的服务器,服务器接收到请求后,经过一系列处理,再返回一个 HTTP 响应
实际上,我们访问一个网站时,一般不会只涉及一次 HTTP 请求/响应的交互过程,一般我们访问一个网站,浏览器(客户端)与服务器之间会进行多次的HTTP 请求/响应的交互。不只是 HTML,可能还有CSS,JS,图片等等。
而且这些 HTTP 请求/响应,在发送之前都会经过层层封装,从应用层封装到物理层,再进行传输。
对方接收到后,也是层层分用,从物理层分用到应用层后,才能使用传输的数据。
HTTP 协议报文格式
我们可以通过抓包来观察 HTTP 协议报文格式,可以使用 Chrome 开发者工具,或者 Fiddler 抓包。
Fiddler 是专门抓 HTTP 的抓包工具,下面我们简单介绍一下 Fiddler 。
Fiddler 抓包工具
Fiddler 下载地址:Fiddler | Web Debugging Proxy and Troubleshooting Solutions (telerik.com)
抓包工具就相当于一个代理,我们通过浏览器访问 CSDN 网站时,就会把 HTTP 请求先发给 Fiddler,然后Fiddler 再把请求转发给 CSDN 的服务器,响应也是一样,Fiddler 会先拿到 HTTP 响应,在将响应给我们的浏览器。
所以通过 Fiddler 这样的抓包工具,就可以很清楚的看到 HTTP 的报文格式了。
Fiddler 的使用
-
左侧显示了所有的 HTTP 请求/响应,可以选中查看详情。
-
右侧就是选中后显示的详情,右侧上方显示了 HTTP 请求的报文内容。
-
右侧下方显示了 HTTP 响应的报文内容。
-
可以选中 Raw 标签页查看详细的数据格式。
-
可以选中右下角的 View in Notepad 通过记事本打开。
HTTP请求格式
这是在 CSDN 登录时,发送的 HTTP 请求。
-
首行:方法 + URL + HTTP版本
-
Header:报文属性,键值对的形式,冒号+空格分割键和值,使用 \n 分割键值对,遇到空行表示 Header 部分结束。
-
空行:在 Header 后, Body 前面,不管有没有Body,空行都存在。
-
Body:空行后面的内容都是Body,Body 允许为空,如果 Body 存在,Header 中的 ,Content-Length 表示 Body 的长度,Content-Type 表示 Body 的格式。
HTTP响应格式
这是在 CSDN 网站登录时,返回的 HTTP 响应。
-
首行:HTTP版本 + 状态码 + 状态码解释
-
Header:报文属性。
-
空行:与请求一样。
-
Body:与请求一样。
空行的作用: 空行是报头和正文的分隔符,是报头的结束标记,HTTP 协议依赖传输层的 TCP 协议,TCP 是面向字节流的,如果没有空行,可能会出现 ”粘包问题“。Body部分不用担心,在 Header 中有 Content-Length 来表示 Body 的长度。
报文格式总结
HTTP 请求详解
方法
方法是为了表达不同的语义的,但是这些方法用起来差别不大,所以现在基本上都是 GET 和 POST,可能GET 占80%,POST占10%,其他方法占10%。
GET 方法
GET 是最常用的方法,用于获取服务器上的某个资源。
-
在浏览器中直接输入网址(URL),浏览器就会发送一个 GET 请求。
-
还有 HTML 中的,link,img,script等标签也会触发 GET 请求。
-
还有使用 JavaScript 也能构造 GET 请求。
GET 请求的特点:
- 首行的第一部分为 GET。
- URL 的 query string 可以为空,也可以不空。
- Body 部分一般为空。
POST 方法
POST 方法也比较常见,一般用于用户提交数据给服务器。
- HTML 中的 form 标签就可以构造 POST 请求。
- 还有 JavaScript 同样可以构造 POST 请求。
POST 请求特点:
-
首行的第一部分为 POST。
-
URL 的一般为空,也可以不空。
-
Body 部分一般不为空,数据内容就在 Body 中,如果 Body 存在,Header 中就会有 ,Content-Length 表示 Body 的长度,Content-Type 表示 Body 的格式。
GET 与 POST 的区别
首先要明确,这些方法是没有本质区别,GET 能做到的事,POST 也能做,POST 能做到的事,GET 也能做,具体要取决于自己写的代码。
-
语义不同:GET 一般用于获取数据,POST 一般用于提交数据。
-
GET 的 Body 一般为空,需要传递的数据可以通过 URL 的 query string 传输,POST 的 query string 一般为空,数据通过 Body 传输。
-
GET 请求一般是幂等的,POST 请求一般不是幂等的(多次请求的结果都相等,就称为幂等)。
-
由于GET是幂等的,POST是不幂等的。所以,一般 GET 可以被缓存,POST 不能被缓存(相同的 GET 请求,响应结果是相同的,所以可以通过缓存避免不必要的传输)。
URL
URL(Uniform Resource Locator),统一资源定位符,就是网址,互联网上的文件都有唯一的URL,URL包含的信息表示互联网上一个文件的位置。
- 协议方案名:常见的是
http
,https
,还有连接数据库的jdbc:mysql
。 - 登录信息:用于网站的身份认证,不过现在一般不用这种方式,一般都会省略。
- 服务器地址:要访问的主机地址,IP地址 或者 域名,域名会通过 DNS 系统解析成一个具体的 IP 地址。
- 服务器端口号:端口号可以省略,如果省略了端口号,浏览器就根据协议类型使用默认端口,
http
协议默认使用 80 端口,https
协议默认使用 433 端口。 - 查询字符串:query string,给服务器传递的自定义信息,键值对结构,形如 id**=123&username=**AAA,键和值用
=
隔开,键值对之间用&
隔开。 - 片段标识符:片段标识符主要用于页面内跳转,可以控制浏览器滚动到页面的某个位置。
Header
HOST
表示服务器主机的地址和端口,端口号可以省略。
Content-Length
表示 Body 中数据的长度,与空行的作用是一样的,HTTP 基于 TCP,TCP 是面向字节流的,这是为了解决粘包问题。
Content-Type
表示 Body 中数据的格式。
请求中 Body 的常见的数据格式:
-
application/x-www-form-urlencoded
-
multipart/form-data
-
application/json
User-Agent
表示 浏览器 / 操作系统 的属性,用来区分不同的浏览器和操作系统,也可以区分手机和PC。
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36 Edg/113.0.1774.42
Referer
表示这个页面是从哪个页面跳转过来的。
直接在浏览器中输入 URL ,或者直接通过收藏夹访问时,是没有 Referer 的。
Cookie
Cookie 是浏览器给网页提供的一种能够持久化存储数据的机制。
-
Cookie 一般存储用户的身份信息,用于实现身份标识的功能。
-
不同域名有不同的 Cookie,不同网站下的 Cookie 之间并不冲突。
-
Cookie 中存储了一个字符串,这个数据可能是客户端 JavaScript 写入的,也可能是服务器在 HTTP 响应的 Header 中 通过 Set-Cookie 字段返回给客户端的。
-
有了 Cookie 之后,后续访问同一个域名下的页面,请求中就会携带上 Cookie 这个字段。
Cookie: buvid3=9EE4E29C-4ECF-4DE4-9536-31B75D11B97D142078infoc; LIVE_BUVID=AUTO7815968828130753; CURRENT_BLACKGAP=0; blackside_state=0; buvid4=B5803E24-E049-112A-9A6F-D0E501F69D5412965-022012116-5IOzIX6vtHKoSWD47JWQ2g%3D%3D; buvid_fp=55c0254a835368d18036fe02cc229b71; browser_resolution=1858-1009; b_lsid=2AC810BEF_1881F549E43; innersign=0
Body
Header 中的 Content-Type ,表示了 Body 的数据格式。
下面列举了三种常见的格式。
- Content-Type: application/x-www-form-urlencoded
form 表单提交的数据格式。
Body 格式形如:
username=AAA&password=123456
- Content-Type:
multipart/form-data
form 标签中加入一个属性 enctyped="multipart/form-data"
,一般用于提交图片/文件。
Header 中的 Content-Type 形如:
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryUHeLvwBzwYsNwk1U
Body 格式形如:
------WebKitFormBoundaryUHeLvwBzwYsNwk1U
Content-Disposition: form-data; name=“Image1”; filename=“zxc.jpg”
Content-Type: image/jpeg数据内容
数据内容
数据内容
boundary=----WebKitFormBoundary1kZA47vzV3AmWLYN
Content-Disposition: form-data; name=“Image2”; filename=“abc.jpg”
Content-Type: image/jpeg数据内容
数据内容
数据内容
------WebKitFormBoundaryUHeLvwBzwYsNwk1U–
boundary 是随机生成的字符串,用来表示数据的边界,因为一次请求可能有多个文件/图片。
- Content-Type: application/json
Body 格式形如:
{“username”:“AAA”, “password”:“123456”}
HTTP 响应详解
状态码
状态码表示了访问页面的结果。
下面列举了几个常见的状态码。
-
200 OK (状态码 状态码解释)
表示访问成功,这是最常见的状态码。
-
404 Not Found
表示没有找到资源,说明 URL 标识的文件不存在。
-
403 Forbidden
表示访问被拒绝,有的页面需要权限才能访问,比如没有登录,可能会遇到这种情况。
-
405 Method Not Allowed
表示不支持请求的方法。
-
500 Internal Server Error
服务器内部出现错误,一般是服务器内部代码问题,服务器异常崩溃。
-
504 Gateway Timeout
请求超时,服务器负载较大时,可能会出现这种请求。
-
302 Move temporarily
临时重定向,登录后跳转到主页,登陆后返回 302 响应,响应的 Header 中有一个 Location 字段,表示要跳转到哪个页面。
-
301 Moved Permanently
永久重定向,当浏览器收到这个响应后,浏览器就会记住响应中的 Location 字段,后续访问的请求都会被改成这个网址。
Content-Type
响应中 Body 的常见的数据格式:
text/html
text/css
application/javascript
application/json