☰
网络原理HTTP
2026/10/2 8:26:43 网站建设 项目流程

1. HTTP

1.1 HTTP是什么

HTTP(超文本传输协议)是常用的应用层协议,基于TCP传输协议实现的,平时我们打开一个网站就是通过HTTP协议传输数据的,我们在浏览器输入网址URL(例如baidu.com)时浏览器给服务器发送一个HTTP请求,然后服务器返回HTTP响应。

1.2 理解HTTP协议工作过程

前面说HTTP基于TCP的,如果说TCP是管通信的,那么HTTP是管说什么的。

维度HTTPTCP
所属层级应用层传输层
关心什么数据的格式与语义(说什么)数据的可靠传输(怎么送)
理解内容吗✅ 完全理解(知道是网页请求)❌ 完全不理解(只是一串字节)
典型动作构造请求、解析响应三次握手、重传、排序、流控
典型标识URL、方法、状态码IP + 端口、序列号
类比你写信的内容邮政系统

我们访问一个网站时涉及不止一次HTTP响应,检查网站的network模块就会显示每一次HTTP响应的结果

2. HTTP协议格式

2.1 抓包工具使用

一个文本协议格式,可以通过fiddler等抓包工具分析HTTP请求/响应的细节。

进去fiddler点击一个HTTP,右边弹出上下两个窗口(上面请求,下面响应),点击raw查看数据格式,点击右下角可以在记事本里查看。

2.2 抓包工具原理

客户端请求发给fiddler,fiddler再发给服务器,服务器返回数据,数据先到fiddler,再到客户端。

2.3 抓包结果

(1)请求

POST https://self.events.data.microsoft.com/OneCollector/1.0/ HTTP/1.1 Accept: */* APIKey: d019ee4b0f-a02c-84 Client-Id: NO_AUTH Content-Encoding: deflate Content-Type: application/bond-compact-binary Expect: 100-continue SDK-Version: EVT-Windows-C++-No-3.4.276.7 Upload-Time: 1790732952702 Host: self.events.data.microsoft.com Content-Length: 606 Connection: Keep-Alive Cache-Control: no-cache

首行:方法+url+版本。

header:请求的属性,冒号分隔的键值对,每组之间用\n(换行符)分隔,到空行结束。

body:空行后面的内容,body可以为空,如果body存在,header里会有一个content-length来表示body的长度。

注意:如果Content-Encoding字段是gzip表示正文经过了 gzip 压缩——无论正文原本是文本还是二进制。压缩通过消除冗余减少字节数,从而省带宽。

(2)响应

HTTP/1.1 403 Forbidden Content-Type: application/json Server: Microsoft-HTTPAPI/2.0 Strict-Transport-Security: max-age=31536000 Collector-Error: All Events Throttled. Access-Control-Allow-Headers: Strict-Transport-Security,Collector-Error,Content-Type,Content-Length Access-Control-Allow-Methods: POST Access-Control-Allow-Credentials: true Access-Control-Allow-Origin: * Access-Control-Expose-Headers: Collector-Error Date: Wed, 30 Sep 2026 01:49:16 GMT Content-Length: 52 {"acc":0,"rej":1,"efi":{"EventLevelThrottling":[0]}}

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

header:请求的属性,冒号分隔的键值对,每组之间用\n(换行符)分隔,到空行结束。

body:空行后面的内容,body可以为空,如果body存在,header里会有一个content-length来表示body的长度,如果返回一个HTML页面,那么HTML页面就是在body里。

2.4 协议格式总结

思考:为什么HTTP报文里存在空行?

报文没有规定键值对的个数,空行就是报头的结束标记,也是与正文分隔符,HTTP基于TCP进行传输的,TCP是面向字节流传输的,如果没有空行就会出现粘包问题。

我们通过抓包可以判断bug在前端还是后端:

  1. 浏览器发出的请求错了→前端错误
  2. 请求正确,响应错误→后端错误
  3. 请求正确,响应正确,显示错误→前端错误

3. HTTP请求

3.1 认识URL

(1)URL基本格式

https://www.example.com:443/path/to/page?key1=value1&key2=value2#section └─┬─┘ └──────┬──────┘ └┬┘ └─────┬─────┘ └──────────┬─────────┘ └───┬───┘ scheme host port path query fragment 协议 主机名 端口 路径 查询参数 片段

https:协议名,常见的有http和https

www.example.com:服务器地址,此处是一个域名,需要通过DNS解析成一个IP地址,我们可以通过ping命令来获取IP地址,如:

端口号:有的URL端口号会被省略,省略时浏览器会根据协议类型⾃动决定使用哪个端口,

例如http协议默认80端口,https默认443端口。

/path/to/page:带层次的文件路径。

?key1=value1&key2=value2:查询字符串,本质是键值对,键值对之间使用&分隔,前面的问号代表查询,这些键值对的含义都是程序员自定义的。

片段标识:主要用于页面内跳转,例如看java官方文档,通过不同的片段标识跳转到不同章节。

URL中可省略的部分:协议名、IP地址、端口号、带层次的文件路径、查询字符串、片段标识。

URL通俗解释:

http://万达茶百道:2/奶茶/杨枝甘露?甜度=五分糖&冰量=去冰&加料=珍珠#杨枝甘露
URL 部件店里对应
http://点单方式:柜台口头报(明文)or 小程序加密下单(HTTPS)
万达茶百道IP 地址:定位到这家店
:2端口号:2 号取餐窗口
/奶茶/杨枝甘露path:品类 → 杯名,层层深入
?甜度=五分糖&冰量=去冰query string:同一杯奶茶,参数不同结果不同
#杨枝甘露打开电子菜单时直接跳到那款的位置——只在你的手机里生效,店员永远看不到

(2)URL encode

例如 / ? : 等这样的字符不能随意出现(如 ?在前面说是URL里代表查询的含义),这些字符需要进行转义。

转义规则:将需要转码的字符转为16进制,然后从右到左,取4位(不足4位直接处理),每2位做一位,前⾯加上%,编码成%XY格式

'+' │ ① 转16进制 ▼ ASCII 0x2B(十进制 43) │ ② 判断:0x2B < 0x80,单字节,"不到4位直接处理"的情况 ▼ 十六进制就是 2B —— 正好 2 位 = 1 字节,无需切分 │ ③ 前面加 % ▼ %2B 两个加号 → %2B%2B

3.2 认识方法

方法说明支持的HTTP协议版本
GET获取资源1.0、1.1
POST传输实体主体1.0、1.1
PUT传输文件1.0、1.1
HEAD获得报文首部1.0、1.1
DELETE删除文件1.0、1.1
OPTIONS询问支持的方法1.1
TRACE追踪路径1.1
CONNECT要求用隧道协议连接代理1.1
LINK建立和资源之间的联系1.0
UNLINE断开连接关系1.0

(1)get方法

最常用的http方法,用于获取服务器上某个资源,在浏览器里直接输入URL(www.baidu.com),此时浏览器就会发出get请求。

通过fiddler抓包工具可以看到:

get请求特点:

  • 首部第一行为GET
  • URL的查询条件可以为空,也可以不为空
  • header部分有若干个键值对结构
  • body部分为空

(2)post方法

多用于用户输入数据提交给服务器,例如用户登录。

通过HTML中的form标签可以构造POST请求,或者使用JavaScript的ajax也可以构造POST请求。

登录boss直聘(输入账号信息之后)抓包:

post请求特点:

  • 首行第一部分为POST
  • URL的查询条件一般为空(也可以不为空)
  • header部分有若干个键值对
  • body部分一般不为空,body里的数据格式一般通过content-type指定的,body长度有content-length指定的。

(3)GET和POST的区别

  • get一般用于获取数据,post一般用于提交数据。
  • get的body通常为空,需要传输的数据通过query传输,post的query通常为空,需要传输的数据装到body里传输。
  • get的请求一般是幂等的,post不是幂等的(多次请求得到的结果一样就是幂等),例如查询10次结果都一样,提交10次订单就产生10个订单。
  • get可以被缓存,post不能被缓存(承接幂等性,GET 靠地址找货,缓存可放心复用;POST 每次执行都改变世界,缓存复用就是造假)。

(4)其他方法

  • PUT(修改)与POST(新增)相似,只是具有幂等特性,⼀般用于更新。
  • DELETE删除服务器指定资源。
  • OPTIONS返回服务器所支持的请求方法。
  • HEAD类似于GET,只不过响应体不返回,只返回响应头。
  • TRACE回显服务器端收到的请求,测试的时候会用到这个。
  • CONNECT预留,暂无使用。

3.3 认识请求报头(header)

header的整体格式是键值对结构

(1)Host

表示服务器的地址和端口。地址必须写,端口可省略——省略时按协议补默认值(http → 80,https → 443)。

例如访问 https://www.gitee.com,完整形式是www.gitee.com:443,因 443 是默认端口,实际就写成www.gitee.com

Host = 把 URL 的主机部分抄进 HTTP 报文,让一台服务器(一个 IP 挂多个站)能分辨"你要哪个站"(虚拟主机)。HTTP/1.1 起强制要求携带,缺失返回 400。

注意:www只是一个子域名,不是必须的。gitee.com和www.gitee.com都能访问,有些网站必须加www才能访问,是因为它只配了www的DNS记录,没配裸域名的反过来也有网站必须不加 www才能访问。

(2)Content-Length

表示body中的数据长度,前提是存在body

服务器如何区分一个完整的请求:

  • 如果没有body就读到空行就行
  • 如果有body则必然存在content-length,找到空行,空行之后就是body,从空行后开始按照content-length长度读取字节数即可

(3)Content-Type

表示请求的body中的数据格式,前提是存在body

大类代表类型对应文件一句话用途
text/*text/html.html网页文档,浏览器渲染成页面
application/*application/json.json前后端 API 传 JSON(本类还有表单/上传/二进制,见下)
image/*image/jpeg.jpg / .jpeg图片(注意:标准写法是 jpeg,没有 image/jpg)
audio/*audio/mpeg.mp3音频
video/*video/mp4.mp4视频
multipart/*multipart/form-data—文件上传,一个 body 分多段
font/*font/woff2.woff2网页字体

如果一个请求/响应,虽然有 body 但是没有 Content-Type 或者 Content-Length,就是一个非法的"请求/响应"。

比如响应中如果没有 Content-Type,浏览器会根据 body 中的数据,"猜"一个格式(有较大的概率能猜对)。

如果没有 Content-Length,浏览器也能猜(按照下一个请求一定是 GET/POST 开头)。

(4)User-Agent(简称UA)

Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/153.0.0.0 Safari/537.36

Windows NT 10.0; Win64; x64表示操作系统信息

AppleWebKit/537.36 (KHTML, like Gecko) Chrome/153.0.0.0 Safari/537.36表示浏览器信息

(5)Referer

表示当前这个页面从哪个页面跳转过来的。

浏览器的回退和referer不同,回退不依赖http协议,浏览器自身维护一个“栈”保存访问记录。

(6)Cookie

cookie里存储了一个字符串(键值对的形式表现),这个数据可能是通过客户端(网页)自行通过JS写入的,也可能来自于服务器(服务器在响应的header里通过Set-Cookie字段给浏览器返回数据)。

登录操作:

最初没有Cookie,发出登录请求,服务器响应返回Set-Cookie,用户访问网站其他页面就会带着获取的Cookie信息来访问。

登录成功 → 服务器返回 sessionId(Set-Cookie里键值对之一) → 浏览器存 Cookie → 后续请求自动带 Cookie → 服务器认出你,不用重新登录

理解登录过程:

  • 左:客户端
  • 右:服务器

注意:Cookie存浏览器就是存本地

(7)session和Cookie的联系

Cookie是票据,Session是档案柜,数据存在服务器的档案柜里,Cookie 里只放一张写着柜号(sessionId)的票。

① 你登录成功 ② 服务器生成一份 Session(存你的用户信息)放在自己"档案柜"里 ③ 服务器把这份 Session 的编号(sessionId)放进响应头: Set-Cookie: sessionId=abc123; HttpOnly ④ 浏览器把这条 Cookie 存在本地 ⑤ 之后每次请求,浏览器自动带上:Cookie: sessionId=abc123 ⑥ 服务器凭编号回档案柜查你的信息 → 确认"是你",返回你的数据

桌面应用app不依赖Cookie,因为数据可以存本地(文件系统)。

3.4 认识请求正文(body)

数据格式:

Content-Type数据格式示例内容说明
application/jsonJSON{"key": "value"}前后端交互最常用的数据格式
text/htmlHTML<div>hello</div>网页源码,浏览器渲染成页面
text/cssCSS* { font-size: 12px; }样式表,控制网页外观
application/javascriptJSlet n = 10;脚本代码,控制网页行为
image/png二进制二进制内容图片,浏览器解析成图像显示

登录网站请求:

POST /wapi/zpCommon/toggle/all HTTP/1.1 Host: www.zhipin.com Connection: keep-alive Content-Length: 39 Content-Type: application/x-www-form-urlencoded Accept: application/json, text/javascript, */*; q=0.01 Accept-Encoding: gzip, deflate, br, zstd Accept-Language: zh-CN,zh;q=0.9,en;q=0.8 Origin: https://www.zhipin.com Referer: https://www.zhipin.com/city/ User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) ... Edg/154.0.0.0 X-Requested-With: XMLHttpRequest Sec-Fetch-Site: same-origin Sec-Fetch-Mode: cors Sec-Fetch-Dest: empty sec-ch-ua-platform: "Windows" sec-ch-ua-mobile: ?0 system=9E2145704D3D49648DD85D6DDAC1CF0D

4. HTTP响应

4.1 认识状态码

(1)200 OK

场景的状态码,表示响应成功

然后响应的body(经过压缩后的数据):

(2)404 Not Found

输入www.sogou.com/index2.html

fiddler:

浏览器:

(3)403 Forbidden

用户访问被拒绝,例如不登录访问Gitee的私有仓库。

(4)405 Method Not Allowed

HTTP中所支持的方法有 GET、POST、PUT、DELETE 等。

但是对方的服务器不一定都支持所有的方法(或者不允许用户使用一些其他的方法)。

(5)500 Internal Server Error

服务器内部错误,服务器代码执行过程遇到特殊情况(如服务器异常崩溃)。

(6)504 Gateway Timeout

服务器负载较大的时候,处理单条数据消耗的时间很长,可能出现超时的情况。

(7)302 Move temporarily

临时重定向。就相当于手机号码中的"呼叫转移"功能。

比如我本来的手机号是 186-1234-5678,后来换了个新号码 135-1234-5678,那么不需要让我的朋友知道新号码,只要我去办理一个呼叫转移业务,其他人拨打 186-1234-5678,就会自动转移到 135-1234-5678 上。

(8)301 Moved Permanently

永久重定向。当浏览器收到这种响应时,后续的请求都会被自动改成新的地址。

(9)状态码小结

类别类别说明原因短语
1XXInformational(信息性状态码)接收的请求正在处理
2XXSuccess(成功状态码)请求正常处理完毕
3XXRedirection(重定向状态码)需要进行附加操作以完成请求
4XXClient Error(客户端错误状态码)服务器无法处理请求
5XXServer Error(服务器错误状态码)服务器处理请求出错

4.2 认识响应报头

Content-Type ,Content-Length等属性和请求报头一个含义。

(1)content-type

常见取值:

  • text/html:body 数据格式是 HTML
  • text/css:body 数据格式是 CSS
  • application/javascript:body 数据格式是 JavaScript
  • application/json:body 数据格式是 JSON

4.3 认识响应正文(body)

(1)text/html

(2)text/css

(3)application/javascript

(4)application/json

5. 构造HTTP请求

通过Java socket构造HTTP请求

package network.HTTP; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; public class HttpClient { private Socket socket=null; public HttpClient(String serverIp,int port) throws IOException { socket=new Socket(serverIp,port); } public void get(String path) throws Exception{ //构造Http结构字符串 try(InputStream inputStream=socket.getInputStream(); OutputStream outputStream=socket.getOutputStream()){ String firstLine ="GET "+path+" HTTP/1.1\r\n"; String header="Host:" +socket.getInetAddress().getHostAddress()+":"+socket.getPort()+"\r\n"; String blankLine="\n"; String httpRequest=firstLine+header+blankLine; outputStream.write(httpRequest.getBytes()); outputStream.flush(); byte[] bytes=new byte[1024*1024]; int n=inputStream.read(bytes); String httpResponse=new String(bytes,0,n); System.out.println(httpResponse); }catch (Exception e){ e.printStackTrace(); } return; } public static void main(String[] args) throws Exception{ HttpClient httpClient=new HttpClient("www.baidu.com",80); httpClient.get("/");//获取首页 } }

响应结果(返回HTML):

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询