✧(≖ ◡ ≖✿
目录
浏览器作为客户端,我的代码作为服务端。
抓取浏览器的HTTP格式的请求
请求行格式
请求行
请求头
空行
正文
请求方(Request)
POST举例Login.html
见资源绑定(测试)
服务端应答
状态行:
响应报头
响应正文(最重要、最核心)
本质
最基本的浏览器响应
浏览器的强大解析能力[了解]
🔗html及图片显示gitee
浏览器作为客户端,我的代码作为服务端。
链接过程如下
我的浏览器(Win) |发送HTTP请求到 122.152.208.179:8080(公网IP+服务端开放端口号) | 互联网路由 |路由转发 云服务商网络 |防火墙允许8080端口 云服务器(122.152.208.179) |操作系统将数据交给监听8080的进程 | 你的serverTCP程序 |解析HTTP请求 返回HTTP响应 |原路返回 浏览器显示内容抓取浏览器的HTTP格式的请求
GET /favicon.ico HTTP/1.1 Host: 122.152.208.179:8080 Connection: keep-alive User-Agent: Mozilla/5.0 (Linux; Android 15; Pixel 9) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Mobile Safari/537.36 Accept: image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8 Referer: http://122.152.208.179:8080/wwwroot/ Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7 [空行] [正文](选择性)请求格式必然满足下图(本质是字符数组)
请求行格式
注意请求行格式顺序:
请求方法-[空格]-[URI]-[空格]-HTTP版本-换行符
将请求内容通过read()读取后输出
void Start(std::unique_ptr<SocketClass>& clientfd) { _clfd = clientfd->sockfdGet (); // 回显浏览器请求至于显示器 char buf[8096] = { 0 }; int n = read (_clfd, buf, 8095); if(n > 0) { //也可能读不全!!!尝试直接输出 LOG (LogLevel::DEBUG) << "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&"; std::cout << buf; LOG (LogLevel::DEBUG) << "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&"; } else if(n == 0) { LOG (LogLevel::INFO) << "客户端已退出"; exit (0); } else RETFATAL ("read"); }得到
GET / HTTP/1.1 Host: 122.152.208.179:8082 Connection: keep-alive Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7 Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7 ubuntu@VM-0-11-ubuntu:~/e2026/Ubuntu_learning/Auguest/HTTP$表示:
"我是Chrome浏览器用户,使用Windows 10系统,想要访问
http://122.152.208.179:8082/,我接受HTML页面和中文内容,如果支持压缩更好。如果服务器支持HTTPS升级,我也可以接受。"
请求行
GET / HTTP/1.1GET:请求方法表示客户端希望获取资源。
/ : 请求的URI(统一资源标识符),“表示根路径”。
HTTP/1.1:使用的HTTP版本。
请求头
Host: 122.152.208.179:8082 Connection: keep-alive Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7 Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7| 字段 | 值 | 含义 |
|---|---|---|
| Host | 122.152.208.179:8082 | 必填。指定目标服务器地址和端口,支持虚拟主机 |
| Connection | keep-alive | 保持TCP连接复用,避免每次请求重新建立连接 |
| Upgrade-Insecure-Requests | 1 | 告诉服务器客户端支持升级到HTTPS(如果服务器支持) |
| User-Agent | Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36... | 客户端标识:Windows 10系统,Chrome 151版本,基于WebKit内核 |
| Accept | text/html,application/xhtml+xml,application/xml;q=0.9,... | 告诉服务器客户端可接受的响应内容类型,按优先级排序(q值表示权重,q=0.9优先) |
| Accept-Encoding | gzip, deflate | 客户端支持的压缩算法,服务器可用这些算法压缩响应体 |
| Accept-Language | zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7 | 客户端偏好的语言:中文优先,英文其次 |
空行
[空行]请求头之后必定有一个空行,表示请求头结束。之后若存在请求体(正文)(如POST表单的请求数据),则放在空行之后。(由于此处是GET方法,所以一定无正文)
正文
请求方(Request)
| 情况 | 是否有正文 | 说明 | 示例 |
|---|---|---|---|
| GET | ❌ | 获取资源 | 访问网页 |
| POST | ✅ | 传输实体 | 提交表单、上传文件 |
| HEAD | ❌ | 获得报文首部 | 只获取响应头 |
| DELETE | ❌ | 删除文件 | 删除资源 |
| PUT | ✅ | 传输文件 | 更新资源 |
| PATCH | ✅ | 部分更新 |
70%为GET20%为POST10%为其他。
POST举例Login.html
POST常用于像服务端提交数据:提交表单、文件上传、API调用等。
见资源绑定(测试)
效果图演示:
当我们输入登录信息(即传输数据)浏览器请求如下
POST /login HTTP/1.1 Host: 122.152.208.179:8085 Content-Type: application/x-www-form-urlencoded Content-Length: 43 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.9 Accept-Encoding: gzip, deflate, br Connection: keep-alive Upgrade-Insecure-Requests: 1 username=Salad&password=2024019&remember=no最后一行即请求正文:
username=Salad&password=2024019&remember=no即请求正文(未加密,因为使用的是http)
在html内即
注意:GET与POST均不安全均可以被抓包获取,因此常使用https来加密处理。
服务端应答
基本应答内容块
状态行:
HTTP版本-[空格]-[状态码]-[空格]-状态码描述-换行符
响应报头
描述客户端、服务端、响应正文、甚至时间等等信息。
响应正文(最重要、最核心)
是传输到客户端(浏览器),供给解析的内容。
因此为兼容多种格式像:html、cs、js等我们使用二进制读取的方法。
#include<fstream> bool ReadFile1(const std::string filename, std::string& out) { std::ifstream file(filename, std::ios::in | std::ios::binary); if (!file.is_open()) { return false; } out.clear(); std::ostringstream buffer; buffer << file.rdbuf(); if (file.fail() && !file.eof()) { return false; } out = buffer.str(); return true; }在四大模块中无疑正文是最重要的部分,它决定了响应什么。其次就是状态行的解释,供浏览器识别版本协议等信息。(自然最本质的底层信息的发送是基于网络的TCP/UDP协议实现的,ta提供send与accept等接口联系了服务端与客户端)
本质
由此可见http不过在TCP/UDP之上的封装而已,而 js css html则称为“解释性语言”、“应用层开发语言”,而C/C++本质是“底层开发”。
最基本的浏览器响应
浏览器的响应解析必须是基于上图的特定格式,因此有以下最简单格式
// 最基本的 HTTP 响应 const char* minimalResponse = "HTTP/1.1 200 OK\r\n" "\r\n" "Hello World!";即:响应行+空行+正文
浏览器的强大解析能力[了解]
由于浏览器的强大解析能力我们甚至在响应行可以删除部分元素:
状态行甚至可以变成这个样子,都可以正常解析。
HTTP/1 0 O感谢支持,长期连载
欢迎关注