首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >HTTP协议详解:GET/POST、Cookie、状态码,一篇就够了!

HTTP协议详解:GET/POST、Cookie、状态码,一篇就够了!

作者头像
用户11935701
发布2025-12-16 09:02:24
发布2025-12-16 09:02:24
540
举报

前言

在当今互联网时代,HTTP协议作为应用层最核心的通信协议之一,几乎支撑着所有的Web应用、移动App以及API交互。无论是浏览网页、发送请求,还是进行数据交互,HTTP都扮演着至关重要的角色。

然而,HTTP协议看似简单,实则包含许多细节和设计理念。例如:

  • 为什么GET和POST方法有不同的使用场景?
  • 状态码200、404、500分别代表什么含义?
  • Cookie是如何实现用户登录状态的保持的?
  • URL的结构和编码规则是怎样的?

本篇文章将从HTTP协议的基本组成出发,逐步解析请求与响应的结构常见报头的含义GET与POST的区别,以及状态码的分类与作用。此外,我们还会介绍如何使用Fiddler抓包工具分析HTTP通信过程,帮助开发者更深入地理解网络通信机制。

应用层协议

在网络上TCP/IP协议用来负责数据的运输,那么我们运输的数据应该是什么的格式呢?为了保证双方都可以读懂对方发送的数据,因此我们需要约定一个“格式”来保障数据格式的一致性,而这就是应用层协议需要解决的问题。 如果说TCP/IP协议是网络中的“物流系统",那么应用层协议就是数据的“使用说明书”

在应用层涉及到的网络通信协议,很多都是程序员自定制的。

自定义协议:

  1. 根据需求,明确传输那些信息
  2. 约定好信息组织的格式

约定好信息组织的格式有很多种方法:

  1. 行文本:使用某个符号作为分隔符,提前约定好第几个数据的含义,是最原始的一种方法。
代码语言:javascript
复制
账号,昵称,密码,好友数量\n
账号,昵称,密码,好友数量\n
  1. xml:xml和html很类似,但是它的标签内容是可以自定义的(html5现在也允许),可读性好,适合别人阅读,但是冗余信息太多了,在网络传输中要消耗更多的带宽,而在服务器中带宽是最贵的东西,因此现在并不是一种主流方案。
代码语言:javascript
复制
<note>
  <id>George</id>
  <name>John</name>
  <passord>Reminder</passord>
  <body>Don't forget the meeting!</body>
</note>
  1. json:当前最主流的方案,使用键值对的方式传递信息,既保持了可读性,消耗的带宽也比xml要少,因为json是单标签,xml是双标签的。但是仍然存在冗余信息。
代码语言:javascript
复制
{
	id:1001,
	name:"lyf",
	pssord:122
}
  1. protobuf:基于二进制的格式,约定那几个字节存储什么内容,对数据进行压缩,不涉及到json/xml冗余信息了,带宽消耗最少,但是可读性变差了,相当于是用开发效率去换执行效率,性能要求高的场景需要使用,如果性能不要求,还是建议使用json。

当然除了这些自定义的协议之外,还有一些大佬已经搞好的,例如我们接下来要讲的HTTP协议。

HTTP协议

HTTP 诞⽣与1991年. ⽬前已经发展为最主流使⽤的⼀种应⽤层协议,被广泛用于web开发/app开发中,目前HTTP最新版已更新到3.0,但是目前最流行的仍然是20年前的1.1版本。HTTP采用一问一答模式,客户端发一个请求,服务器就返回一个响应,请求和响应一一对应。

抓包工具fiddler

如果要分析网络的通信过程,一个抓包工具是必不可少的,抓包工具可以让电脑上所有的网络通信必须先通过它再进行转发,而这个过程我们就可以分析他们发送和接收的内容

这里我们选用fidder来作为我们的抓包工具,fidder是专门用来抓取http协议的工具,功能简单,使用也很简单。

下载地址

我们下载时要下载经典版,最新版现在收费,安装流程这里并不过多赘述,当然你不安装也不影响本文章的后续内容。

打开之后进入的页面如下:

刚打开时左侧可能一下子蹦出来很多的信息,这是因为你后台的应用实际上并不安分,一直在和服务器之间进行沟通,而我们的抓包工具都给这些信息全部抓获了。

点开数据信息后,他给的信息我们可能看不懂,我们可以在这里点击raw选项,让其还原成最初始的HTTP语句。

响应数据经常是压缩过的二进制数据,展现成一段乱码,而该工具是自带解码的,因此我们只需要在出现这个选项时点击它即可解码成正常数据。

除此之外,我们还可以发现左侧的抓包信息的颜色参差不齐,不同的颜色代表不同的含义,红色表示报错,蓝色表示响应是一个网页,绿色表示得到了一个js格式的数据,灰色则表示这个响应的数据已经被缓存了。

协议组成

安装好抓包工具后,就可以对HTTP进行抓取了,http协议本质上是文本格式的协议,更加具体的信息可以查看http的rfc标准文档:rfc文档

请求信息

请求信息由四部分组成:

  1. 首行: 包括请求方法、URL以及HTTP版本号,GET https://www.csdn.net/ HTTP/1.1
  2. 请求头: 键值对结构,每一行是一个键值对,键和值之间使用空格隔开,有哪些键,这些键可以取那些值,都是已经规定好的,sec-ch-ua-platform: "Windows"
  3. 空行: 请求头的最后一行是一个空行,用来标识请求头结束了。
  4. 正文:有些请求没有正文,有些有。

以下是我使用fiddler抓取的一个请求信息,可当做参考:

代码语言:javascript
复制
POST https://eva2.csdn.net/v3/06981375190026432f77c01bfca33e32/lts/groups/dadde766-b087-42da-8e67-d2499a520ee7/streams/5da0dae3-481b-478b-92ca-3caa293e4a29/logs HTTP/1.1
Host: eva2.csdn.net
Connection: keep-alive
Content-Length: 1161
sec-ch-ua-platform: "Windows"
sec-ch-ua: "Chromium";v="136", "Google Chrome";v="136", "Not.A/Brand";v="99"
sec-ch-ua-mobile: ?0
X-Sdk-date: 20250603T115606Z
Lts-Sdk-Request-Id: e36bfe51ed0b409b9f51c7791a71a122
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36
Content-Type: application/json
Lts-Sdk-Version: 1.0.15
Accept: */*
Origin: https://mpbeta.csdn.net
Sec-Fetch-Site: same-site
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://mpbeta.csdn.net/
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7

{"labels":{},"logs":[{"contents":[{"pid":"mpbeta","ref":"https://mpbeta.csdn.net/","curl":"https://mpbeta.csdn.net/mp_blog/manage/article?spm=1000.2115.3001.5448","spm":"1011.2415","disabled":"true","extra":"{\"version\":\"new\"}","tos":0,"adb":0,"cCookie":"c_ab_test=1;c_session_id=10_1748950839573.109676;c_first_ref=default;c_first_page=https%3A//www.csdn.net/;c_dsid=11_1748950840378.769273;c_segment=2;c_sid=2027680f8c25c20fdd506cf78e2f2a67;c_page_id=default;c_pref=https%3A//editor.csdn.net/;c_ref=https%3A//www.csdn.net/;","t":1748951766,"screen":"1440*900","urn":"1748951766184-d4c434cd-3802-49aa-a879-d0357d710c5c","vType":"U010000","log_id":"5","sign":"0d3dc2f82f21b9c90a67228fc4ee4a91","lscreen":"1440*900","hca":"F268FC93106CB2BC","userAgent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36","cid":"10_18662895060-1748744031688-432578","uid":"to_mountain","sid":"10_1748950839573.109676","dc_sid":"2027680f8c25c20fdd506cf78e2f2a67","did":"10_18662895060-1748744031688-432578","utm":"","un":"to_mountain","fid":"20_56679795187-1748744032956-330580","__client_time__":1748951766188}]}]}
响应信息

响应信息的构成和请求很相似,也是由四部分组成:

  1. 首行: 包括版本号、状态码、状态码描述,HTTP/1.1 200 OK
  2. 响应头(Header): 也是键值对结构,每一行是一个键值对,键和值之间使用空格隔开,键值对和请求有区别,有些重要的键值对在请求和响应中都存在,Content-Type: text/html;
  3. 空行: 响应头的最后一行是一个空行,用来标识响应头结束了。
  4. 正文(Body):这个响应可以是html/json或者一些其他类型。

以下是抓取到的部分响应数据:

代码语言:javascript
复制
HTTP/1.1 200 OK
Server: nginx
Date: Wed, 28 May 2025 09:10:48 GMT
Content-Type: text/html; charset=utf-8
Connection: keep-alive
Vary: Accept-Encoding
Set-Cookie: SNUID=D0E28FDCB3B5859D3C3ABEC3B37C5F65; expires=Thu, 28-May-26 09:10:48 GMT; domain=.sogou.com; path=/
Pragma: No-cache
Cache-Control: max-age=0
Expires: Wed, 28 May 2025 09:10:48 GMT
UUID: f8a02e75-0760-4628-ab51-8d55bda3fee3
Content-Length: 15858

<!DOCTYPE html><html lang="cn"><head> <meta name="baidu_union_verify" content="efd6e8ce094119528f66c2d380f6ec94">
<meta name='360_ssp_verify' content='651669fb99b77a4e4efae7ec25d6796a' /> <meta name="viewport" content="width=device-width,minimum-scale=1,maximum-scale=1,user-scalable=no"><script>window._speedMark = new Date();
window.lead_ip = '111.61.81.98';
window.now = 1748423447974;
window.uuid = 'f8a02e75-0760-4628-ab51-8d55bda3fee3';
window.cuid = 'AAH0RLpVUgAAAAuiUwbjJAAASQU=';</script><script type="text/javascript">/*file=static/js/resourceErrorReport.js*/!function(a){var n=(new Date).getTime(),r=a.location.protocol;function c(e,t){var o=(new Date).getTime()-n;(new Image).src=["//pb.sogou.com/pv.gif?uigs_productid=wapapp&type=resource-
url组成

在上述的请求信息的首行中,我们提到过url这一词,其全称名为:统一资源定位系统,url是描述网络上的唯一资源的位置的,url不是http专属的概念,他可以给各种协议提供支持,是一个网络中比较通用的概念,可以用来标识给那个协议进行服务的。

url在我们生活中很常见,例如你访问的网址就是一个url。

代码语言:javascript
复制
https://mpbeta.csdn.net/mp_blog/manage/article?spm=1000.2115.3001.5448

其组成也可分为多个部分:

  1. 协议(Scheme)​:放在开头,例如上述的例子就是使用的https协议, 以:// 结尾。
  2. 域名(Host)​:标识资源所在的服务器地址,一般是ip地址或者域名,在网络中,ip和域名可以相互转换,这个过程通过DNS域名解析系统来完成的。。
  3. 路径(Path)​:在确认了主机和端口号后,就需要确定某个资源,这一般是带有层次结构的路径。
  4. 查询字符串(Query String)​:?后面是查询字符串,表示对要访问的资源进行补充说明,也是键值对结构,使用&进行分割,键和值直接使用=,此处的键值对怎么写时程序员自定义的。
  5. 片段(Fragment)​:指向资源内的某个特定部分(如页面锚点),现在用的少了,文档类的网站常见。

URL转义

在url中有一些特殊的符号表示不同的含义,例如::/&之类,而我们的查询字符串是我们程序员自定义的,万一你里面包含有这些特殊的字符咋办?因此它对各种字符进行了转义,其中也包括了汉字等,每个字节取出来16进制表示,前面加上%,汉字用的是utf8编码。

代码语言:javascript
复制
?ie=utf-8&f=8&rsv_bp=1&tn=68018901_45_oem_dg&wd=%EF%BC%9A%27a
请求方法

HTTP中的请求方法用于表示这次的请求要干什么,下述内容看似很多,但是我们只需要了解GET以及POST方法即可,因为最初时只有GET和POST,后来逐渐才有其他的,因此GET和POST方法占据了日常中的大多数使用。

GET方法特点

GET ⼀般⽤于获取数据,例如获取html、css、js等操作,GET请求一般是没有body的,如果要通过GET发送数据,使用url中的query string传递过去,body部分一般为空。GET还通常建议设计成幂等的(标准建议),POST则无要求。

幂等性是计算机科学和数学中的重要概念,指对同一个操作重复执行多次所产生的影响与执行一次的影响相同

POST方法特点

多⽤于提交⽤⼾输⼊的数据给服务器(例如登陆⻚⾯),URL 的 query string ⼀般为空 (也可以不为空),body 部分⼀般不为空,通过body传输数据。

GET和POST的区别

首先GET和POST本质上并没有区别,它俩完全可以混用,用GET去登录页面,用POST获取数据也是没有任何问题的,它俩主要是是语义上的不同。

  1. 使用场景上:GET ⼀般⽤于获取数据, POST ⼀般⽤于提交数据。
  2. 传递数据方式上:GET 的 body ⼀般为空, 需要传递的数据通过 query string 传递, POST 的 query string ⼀般为空, 需要传递的数据通过 body 传递。
  3. 设计方式上:GET 请求⼀般是幂等的, POST 请求⼀般是不幂等的. (如果多次请求得到的结果⼀样, 就视为请求是幂等的)。
  4. 存储方式上:GET 可以被缓存, POST 不能被缓存(这⼀点也是承接幂等性,如果多次请求结果不一样存储就没意义了)。

注:上述使用的词是一般,并不代表是绝对的。

常见问题

1. POST比GET更安全?

并不是,这个问题的产生是由于在传输数据时,GET方法在传输数据时是在url中传输的,它会在上方的网址中显示出你输入的信息,可能会误以为它会泄露你的账号或者密码之类的。但是实际上安不安全是由你的传输是否加密决定的,如果你不加密即使使用的POST方法也很容易获取到你的数据,只要是明文传输,就不存在安全的情况。

2. GET传输数据有长度限制?

首先在HTTP标准中并没有规定长度限制,但是在上古时期存在这个情况,在以前浏览器的URL的长度是存在限制的,如果传输太多可能会被截断,但是现在的主流浏览器早就没有这种限制了。

3. GET只能传输文本,POST可以传输二进制?

GET方法的url里面确实只能放文本,但这并不代表它无法传输二进制,首先GET也不是完全不能带body,但是有些客户端/服务器可能不支持,其次我们也可以将二进制转换为 Base64 编码进行传输。

Restful风格

在Restful风格是设计服务器接口的一种习惯,在实现这些api的时候会用到其他的请求方法。

该风格是这么实现的:

POST:用于新增。 DELETE:用于删除。 PUT:用于修改。 GET:用于查询。

(其实这四个都可以进行增删改查,但是是这么规定的)

常见报头
Host

他是一个请求头,表示服务器主机的地址和端口,在 HTTP/1.1 中,所有请求必须包含 Host 头(否则返回 400 Bad Request),Host 头通常与请求 URL 中的域名一致,但可能不同(如反向代理场景)。

代码语言:javascript
复制
Host: rumt-zh.com
Content-Lenth & Content-Type

Content-Lenth:表示body 中的数据长度,单位是字节。

Content-Type:表示body中的数据格式。

这两个头在请求和响应都有,如果有body但没有这两个头就认为是非法的报文,它俩存不存在也取决于是否有body部分。

作用:

当请求或者响应存在多个时,如何进行区分它们呢?

header和body之间有一个空行,因此可以用空行区分header,而body的区分就是通过Content-Lenth的值,读取这个长度的值,并用Content-Type的格式进行解析。

代码语言:javascript
复制
Content-Type: application/x-javascript
Content-Length: 92633
User-Agent

简称UA,表示了用户使用的设备的浏览器和操作系统的情况。

例如:

代码语言:javascript
复制
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36

Mozilla:火狐浏览器创始人名字

Windows NT:windows版本

x64:cpu环境

AppleWebKit:浏览器内核

Chrome/136.0.0.0:浏览器版本

Safari/537.36:苹果手机的浏览器

作用:

可以用于区分用户使用的设备,例如PC端和手机端使用不同尺寸的页面来适配用户的使用。

Referer

描述了当前的页面的来源,这个页面从哪个页面跳转过来的,当然直接输入url/点收藏栏打开的页面是没有Referer的。

作用:

广告平台(如 Google Analytics)通过 Referer 统计用户来源,计算转化率。网站可以用 Referer 判断请求是否来自自己的域名,防止其他网站盗用资源(如图片、视频、API)。

代码语言:javascript
复制
Referer: https://facebook.com/ads/click?ad_id=123
Cookie

浏览器持久化存储在本地的一种方式,使用键值对进行存储。

首先浏览器是无法直接访问用户的文件的,因此诞生了Cookie这种方法进行存储,浏览器保存了这些Cookie后,后续给服务器发送请求的时候,把这些cookie键值对放到请求Cookie header中传输到服务器里面。

代码语言:javascript
复制
Cookie: SUID=62513D6F5B54A20B0000000067D6CFF4; cuid=AAH0RLpVUgAAAAuiUwbjJAAASQU=; SUV=00BA49EE6F3D516267D6CFF6C5F9E068; SMYUV=1745122380511658; SNUID=D9EB86D5BABD8DD6D231D1CABBEEA7DC; wuid=AAEV+t3cUwAAAAuipaVKygEAkwA=; arialoadData=false; front_screen_resolution=1440*900; front_screen_dpi=1; IPLOC=CN1308; LSTMV=257%2C410; LCLKINT=3344; ssuid=7396569824

键值对是程序员自定义的,所以看不懂很正常,大多数都是和业务相关的。

在我们的浏览器点击F12可以查看到我们本地存储的值。

作用:

一个典型的案例就是登录和用户认证,在大多数的网站中登录是只需要一次的,第二次进入不需要登录,而这就是通过保存会话信息实现的:

  1. 用户提交登录信息。
  2. 服务器验证,并发送一个会话id保存到客户端的Cookie中,服务器使用哈希表将会话id和会话信息保存到服务器中。
  3. 用户再次登录时发送会话id到服务器
  4. 服务器根据哈希表找到之前的会话信息,并返回给客户端。

Cookie是带有存储时间的,当超过存储时间就会自动删除,这也就是为什么有的网页登录一次后过一段时间还需要再登录。

除此之外你也可以自己尝试一下将自己网页里面的Cookie都删掉,观察一下是否需要重新登录。

状态码

状态码:返回出错原因的关键手段,良好的设置状态码,可以帮我们快速找到bug

状态码

名称

描述

200

OK

请求成功,服务器已返回请求的数据。

302

Move Temporarily

临时重定向,服务器要求客户端访问另一个 URL(如域名跳转)。

403

Forbidden

访问被拒绝,服务器理解请求但拒绝执行(如权限不足)。

404

Not Found

资源未找到,URL 对应的资源在服务器上不存在。

405

Method Not Allowed

请求方法不被允许(如用 GET 访问只支持 POST 的接口)。

500

Internal Server Error

服务器内部错误,代码逻辑异常未被捕获(如未处理的异常)。

504

Gateway Timeout

网关超时,服务器作为网关或代理时未及时从上游服务器收到响应。

以上是一些常见的状态码,但是我们不必死记硬背,他们有规律,2开头可以认为成功,3开头都是重定向,4开头客户端出错,5开头服务器出错,1开头的状态码并没有被定义,除非在某些试验条件下,服务器禁止向此类客户端发送。

感谢各位的观看Thanks♪(・ω・)ノ,如果觉得满意的话留个关注再走吧。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-12-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 应用层协议
  • HTTP协议
    • 抓包工具fiddler
    • 协议组成
      • 请求信息
      • 响应信息
    • url组成
    • 请求方法
      • GET方法特点
      • POST方法特点
      • GET和POST的区别
      • 常见问题
      • Restful风格
    • 常见报头
      • Host
      • Content-Lenth & Content-Type
      • User-Agent
      • Referer
      • Cookie
    • 状态码
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档