应用层协议 HTTP
HTTP 协议
虽然我们说, 应用层协议是我们程序猿自己定的. 但实际上, 已经有大佬们定义了一些现成的, 又非常好用的应用层协议, 供我们直接参考使用. HTTP(超文本传输协议)就是其中之一。
在互联网世界中,HTTP(HyperText Transfer Protocol,超文本传输协议)是一个至关重要的协议。它定义了客户端(如浏览器)与服务器之间如何通信,以交换或传输超文本(如 HTML 文档)。HTTP 协议是客户端与服务器之间通信的基础。客户端通过 HTTP 协议向服务器发送请求,服务器收到请求后处理并返回响应。HTTP 协议是一个无连接、无状态的协
议,即每次请求都需要建立新的连接,且服务器不会保存客户端的状态信息。
认识 URL
平时我们俗称的 “网址” 其实就是说的 URL
urlencode 和 urldecode
像 / ? : 等这样的字符, 已经被 url 当做特殊意义理解了. 因此这些字符不能随意出现. 比如, 某个参数中需要带有这些特殊字符, 就必须先对特殊字符进行转义. 转义的规则如下:
将需要转码的字符转为 16 进制,然后从右到左,取 4 位(不足 4 位直接处理),每 2 位做一位,前面加上%,编码成%XY 格式
例如:
“+” 被转义成了 “%2B”
urldecode 就是 urlencode 的逆过程;
urlencode 工具
HTTP 协议请求与响应格式
HTTP 请求
请求格式
- 首行: [方法] + [url] + [版本]
- Header: 请求的属性, 冒号分割的键值对;每组属性之间使用\r\n 分隔;遇到空行表示 Header 部分结束
- Body: 空行后面的内容都是 Body. Body 允许为空字符串. 如果 Body 存在, 则在
Header 中会有一个 Content-Length 属性来标识 Body 的长度;
HTTP 响应
响应格式
- 首行: [版本号] + [状态码] + [状态码解释]
- Header:响应报头。请求的属性 冒号分割的键值对;每组属性之间使用\r\n 分隔;遇到空行,表示Header 部分结束
- Body:空行后面的内容都是Body. Body 允许为空字符串. 如果Body 存在, 则在Header 中会有一个Content-Length 属性来标识Body 的长度; 如果服务器返回了一个html 页面, 那么html 页面内容就是在body 中
HTTP 的方法
方法列表(GET、POST、PUT、HEAD 等)
GET 方法
- 用途:用于请求URL 指定的资源
- 示例:GET /index.html HTTP/1.1
- 特性:指定资源经服务器端解析后返回响应内容。
std::string GetFileContentHelper(const std::string &path)
{
std::ifstream in(path, std::ios::binary); if (!in.is_open())
return "";
in.seekg(0, in.end);
int filesize = in.tellg();
in.seekg(0, in.beg);
std::string content;
content.resize(filesize);
in.read((char *)content.c_str(), filesize);
// std::vector<char> content(filesize);
// in.read(content.data(), filesize);
in.close();
return content;
}
POST 方法
- 用途:用于传输实体的主体,通常用于提交表单数据
- 示例:POST /submit.cgi HTTP/1.1
- 特性:可以发送大量的数据给服务器,并且数据包含在请求体中。
关于post与get
- 两者都可以进行参数的提交
- get提交参数是以uri进行提交的会明确显示,会回显提交参数
- post提交的参数是通过请求正文提交的
- 其实两者提交参数的形式都是不安全的会被抓包 解决办法:https协议
PUT方法
- 用途:用于传输文件,将请求报文主体中的文件保存到请求URL 指定的位置。
- 示例:PUT /example.html HTTP/1.1
- 特性:不太常用,但在某些情况下,如 RESTful API 中,用于更新资源。
HEAD方法
- 用途:与 GET 方法类似,但不返回报文主体部分,仅返回响应头。
- 示例:HEAD /index.html HTTP/1.1
- 特性:用于确认 URL 的有效性及资源更新的日期时间等
DELETE方法
- 用途:用于删除文件,是 PUT 的相反方法。
- 示例:DELETE /example.html HTTP/1.1
- 特性:按请求 URL 删除指定的资源。
OPTIONS方法
- 用途:用于查询针对请求 URL 指定的资源支持的方法。
- 示例:OPTIONS * HTTP/1.1
- 特性:返回允许的方法,如 GET、POST 等
HTTP 的状态码
重定向相关状态码(301、302 等)
HTTP 状态码301(永久重定向):
- 当服务器返回HTTP 301 状态码时,表示请求的资源已经被永久移动到新的位置。
- 在这种情况下,服务器会在响应中添加一个Location 头部,用于指定资源的新位置。这个Location 头部包含了新的URL 地址,浏览器会自动重定向到该地址。
- 例如,在HTTP 响应中,可能会看到类似于以下的头部信息
HTTP/1.1 301 Moved Permanently\r\n
Location: https://www.new-url.com\r\n
HTTP 状态码302(临时重定向):
- 当服务器返回HTTP 302 状态码时,表示请求的资源临时被移动到新的位置。
- 同样地,服务器也会在响应中添加一个Location 头部来指定资源的新位置。浏览器会暂时使用新的URL 进行后续的请求,但不会缓存这个重定向。
- 例如,在HTTP 响应中,可能会看到类似于以下的头部信息:
HTTP/1.1 302 Found\r\n
Location: https://www.new-url.com\r\n
总结:
无论是 HTTP 301 还是 HTTP 302 重定向,都需要依赖 Location 选项来指定资源的新位置。这个 Location 选项是一个标准的 HTTP 响应头部,用于告诉浏览器应该将请求重定向到哪个新的 URL 地址。永久重定向就是会把重定向目标进行缓存下次直接去重定向的资源,临时重定向不会进行缓存每次都要去老的去看看再去重定向目标。
HTTP 常见 Header
- Content-Type: 数据类型(text/html 等) 可以查表看
- Content-Length: Body 的长度
- Host: 客户端告知服务器, 所请求的资源是在哪个主机的哪个端口上;
- User-Agent: 声明用户的操作系统和浏览器版本信息;
- referer: 当前页面是从哪个页面跳转过来的;
- Location: 搭配 3xx 状态码使用, 告诉客户端接下来要去哪里访问;
- Cookie: 用于在客户端存储少量信息. 通常用于实现会话(session)的功能;
Connection 报头与持久连接
HTTP 中的Connection 字段是HTTP 报文头的一部分,它主要用于控制和管理客户端与服务器之间的连接状态核心
核心作用
- 管理持久连接:Connection 字段还用于管理持久连接(也称为长连接)。持久连接允许客户端和服务器在请求/响应完成后不立即关闭TCP 连接,以便在同一个连接上发送多个请求和接收多个响应。
持久连接(长连接)
- HTTP/1.1:在HTTP/1.1 协议中,默认使用持久连接。当客户端和服务器都不明确指定关闭连接时,连接将保持打开状态,以便后续的请求和响应可以复用同一个连接。
- HTTP/1.0:在HTTP/1.0 协议中,默认连接是非持久的。如果希望在HTTP/1.0上实现持久连接,需要在请求头中显式设置Connection: keep-alive。
语法格式
- Connection: keep-alive:表示希望保持连接以复用TCP 连接。
- Connection: close:表示请求/响应完成后,应该关闭TCP 连接。