HTTP——服务端、客户端格式,浏览器解析

@bit::Shadow
✧(≖ ◡ ≖✿

目录

浏览器作为客户端,我的代码作为服务端。

抓取浏览器的HTTP格式的请求

请求行格式

请求行

请求头

空行

正文

请求方(Request)

POST举例Login.html

见资源绑定(测试)

服务端应答

状态行:

响应报头

响应正文(最重要、最核心)

本质

最基本的浏览器响应

浏览器的强大解析能力了解


🔗html及图片显示gitee

浏览器作为客户端,我的代码作为服务端。

链接过程如下

bash 复制代码
我的浏览器(Win)
    |发送HTTP请求到 122.152.208.179:8080(公网IP+服务端开放端口号)
    |
互联网路由
    |路由转发
云服务商网络
    |防火墙允许8080端口
云服务器(122.152.208.179)
    |操作系统将数据交给监听8080的进程
    |
你的serverTCP程序
    |解析HTTP请求
返回HTTP响应
    |原路返回
浏览器显示内容

抓取浏览器的HTTP格式的请求

cpp 复制代码
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()读取后输出

cpp 复制代码
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");
}

得到

bash 复制代码
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升级,我也可以接受。"

请求行

bash 复制代码
GET / HTTP/1.1

GET:请求方法表示客户端希望获取资源。

/ : 请求的URI(统一资源标识符),"表示根路径"。

HTTP/1.1:使用的HTTP版本。

请求头

bash 复制代码
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 客户端偏好的语言:中文优先,英文其次

空行

bash 复制代码
[空行]

请求头之后必定有一个空行,表示请求头结束。之后若存在请求体(正文)(如POST表单的请求数据),则放在空行之后。(由于此处是GET方法,所以一定无正文)

正文

请求方(Request)
情况 是否有正文 说明 示例
GET 获取资源 访问网页
POST 传输实体 提交表单、上传文件
HEAD 获得报文首部 只获取响应头
DELETE 删除文件 删除资源
PUT 传输文件 更新资源
PATCH 部分更新

70%为GET20%为POST10%为其他。

POST举例Login.html

POST常用于像服务端提交数据:提交表单、文件上传、API调用等。

见资源绑定(测试)

效果图演示:

当我们输入登录信息(即传输数据)浏览器请求如下

cpp 复制代码
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

最后一行即请求正文:

cpp 复制代码
username=Salad&password=2024019&remember=no

即请求正文(未加密,因为使用的是http)

在html内即

注意:GET与POST均不安全均可以被抓包获取,因此常使用https来加密处理。


服务端应答

基本应答内容块

状态行:

HTTP版本-空格-状态码-空格-状态码描述-换行符

响应报头

描述客户端、服务端、响应正文、甚至时间等等信息。

响应正文(最重要、最核心)

是传输到客户端(浏览器),供给解析的内容。

因此为兼容多种格式像:html、cs、js等我们使用二进制读取的方法。

cpp 复制代码
#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++本质是"底层开发"。

最基本的浏览器响应

浏览器的响应解析必须是基于上图的特定格式,因此有以下最简单格式

cpp 复制代码
// 最基本的 HTTP 响应
const char* minimalResponse = 
    "HTTP/1.1 200 OK\r\n"
    "\r\n"
    "Hello World!";

即:响应行+空行+正文

浏览器的强大解析能力了解

由于浏览器的强大解析能力我们甚至在响应行可以删除部分元素:

状态行甚至可以变成这个样子,都可以正常解析。

cpp 复制代码
HTTP/1 0 O

感谢支持,长期连载

欢迎关注

相关推荐
dog2501 小时前
写一个时延固定的拥塞控制
网络
酣大智1 小时前
华为 VRRP的抢占延迟时间
网络·tcp/ip·vrrp
那年窗外下的雪.1 小时前
第 02 天:Linux 权限、inode、目录项与链接
学习·http
hengmeida2 小时前
楼宇控制柜标准化项目交付完整规范
大数据·网络·笔记
2501_937860942 小时前
上篇:网络编程基础与UDP套接字编程
java·网络·计算机网络
那年窗外下的雪.2 小时前
AIDC 学习日志|第 27 天|EVPN 多归属收敛时间线与 Leaf2 接管验证
网络协议·学习·http·tcpdump
xixiaoyunya2 小时前
制造业生产数据备份:在“不停产“前提下的自动化实践
网络·安全
Figo_Cheung2 小时前
Figo权重动力学:递归本体论与跨尺度演化的形式化基础——揭示:宇宙的演化,本质上就是一场由无数观测者共同参与的、永不停歇的、跨尺度的权重重构盛宴。
网络·人工智能·量子计算
j7~3 小时前
【Linux】三十八.C++ 手写 HTTP 服务器:裸 socket + fork 多进程,从 HTTP 报文解析到浏览器打开网页
linux·网络·网络协议·学习·http·网络编程
FW-Linker3 小时前
偏远山区户外直播网络优化:多链路聚合如何保障稳定低时延传输
网络·5g·智能路由器