HTTP 协议

发布时间:2026/7/11 14:02:05

HTTP 协议 目录一、HTTP 是什么—— 先搞懂最基础的概念1.1 HTTP 的全称与作用1.2 HTTP 的 2 个核心特点1无连接2无状态二、URL你输入的 “网址” 到底是什么2.1 URL 的完整结构2.2 urlencode 与 urldecode特殊字符的 “翻译官”转义规则实战工具三、HTTP 的 “对话格式”请求与响应3.1 HTTP 请求格式客户端怎么 “提需求”各部分详解3.2 HTTP 响应格式服务器怎么 “回消息”各部分详解3.3 实战手写一个简单的 HTTP 服务器代码实现代码解释四、HTTP 方法不同的 “请求类型” 有什么用4.1 GET 方法“我要获取资源”用途示例特点4.2 POST 方法“我要提交数据”用途示例特点4.3 GET vs POST用 “登录” 举例对比若用 POST若改成 GET五、HTTP 状态码服务器的 “表情符号”5.1 状态码分类按第一位数字5.2 最常用的 5 个状态码1200 OK请求成功2404 Not Found资源不存在3301 Moved Permanently永久重定向4302 Found临时重定向5500 Internal Server Error服务器内部错误5.3 实战实现 302 重定向运行效果六、HTTP Header隐藏的 “附加信息”6.1 Content-Type数据的 “身份证”示例6.2 Cookie 与 Set-Cookie解决 “无状态” 的关键工作流程实战设置 Cookie效果6.3 Connection长连接 vs 短连接长连接的好处七、HTTPS更安全的 “HTTP”7.1 HTTPS 是什么—— HTTP 加密层7.2 为什么需要 HTTPS—— 防止 “中间人攻击”7.3 HTTPS 的核心证书与加密1证书证明服务器 “身份合法”2混合加密兼顾安全与速度7.4 HTTP vs HTTPS关键区别八、总结在我们每天刷网页、聊微信、逛淘宝时背后都有一个 “隐形的信使” 在工作 —— 它就是HTTP 协议。无论是打开百度搜索还是登录抖音账号本质上都是客户端手机 / 电脑通过 HTTP 协议向服务器发送请求再接收服务器响应的过程。这篇博客会从 HTTP 的基本概念讲起一步步拆解它的工作原理结合实战代码让你彻底搞懂这个 “互联网信使”。一、HTTP 是什么—— 先搞懂最基础的概念1.1 HTTP 的全称与作用HTTPHyperText Transfer Protocol超文本传输协议是客户端与服务器之间交换数据的 “语言”。它定义了客户端如何向服务器 “说话”发送请求服务器如何 “回应”返回响应传输的数据格式比如网页、图片、登录信息等。举个例子当你在浏览器输入www.baidu.com时浏览器会自动用 HTTP 协议向百度服务器发送 “我要访问首页” 的请求服务器收到后用 HTTP 协议返回百度首页的 HTML 代码浏览器再解析代码显示出我们看到的页面。1.2 HTTP 的 2 个核心特点1无连接“无连接” 不是说不建立连接而是每次请求完成后连接就会断开。比如你刷淘宝时看第一个商品是一次连接看第二个商品是重新建立连接 —— 不像打电话那样一直 “占线”这样能节省服务器资源支持更多人同时访问。2无状态“无状态” 指服务器不会记住你上一次的操作。比如你第一次访问淘宝时登录了账号第二次再打开淘宝服务器本身不知道 “你就是刚才登录的那个人”—— 这时候就需要 “Cookie” 来帮忙记录状态后面会详细讲。二、URL你输入的 “网址” 到底是什么我们俗称的 “网址”其实是 URLUniform Resource Locator统一资源定位符它的作用是精确找到互联网上的某个资源比如一个网页、一张图片。2.1 URL 的完整结构一个标准的 URL 由 7 部分组成我们以http://user:passwww.baidu.com:80/s?wdHTTP#ch1为例拆解部分示例作用说明协议方案名http://用什么协议访问HTTP/HTTPS/FTP 等登录信息user:pass访问资源的用户名和密码几乎不用隐私性差服务器地址www.baidu.com服务器的域名对应一个 IP 地址比如百度的 IP服务器端口号:80访问服务器的 “门牌号”HTTP 默认 80HTTPS 默认 443带层次的路径/s资源在服务器上的存储路径查询字符串?wdHTTP向服务器传递的参数比如百度搜索的关键词片段标识符#ch1跳转到页面内的指定位置比如文章的第一章注意日常使用中登录信息、端口号默认时、片段标识符经常被省略比如百度搜索的 URL 简化为https://www.baidu.com/s?wdHTTP。2.2 urlencode 与 urldecode特殊字符的 “翻译官”URL 中有些字符有特殊含义比如/表示路径、?表示查询开始如果要传输这些特殊字符或中文就需要 “转义”—— 这就是urlencode服务器收到后再 “还原”—— 这就是urldecode。转义规则将特殊字符转为十六进制前面加%。比如号转义为%2B因为在 URL 中表示空格中文 “你好” 转义为%E4%BD%A0%E5%A5%BDUTF-8 编码下的十六进制。实战工具可以用在线工具验证比如在 “站长工具 - URL 编码 / 解码” 中输入C编码后得到C%2B%2B解码后又能还原为C。三、HTTP 的 “对话格式”请求与响应HTTP 的核心是 “请求 - 响应” 模式客户端发 “请求”服务器回 “响应”。两者都有固定的格式就像写信要按 “收件人、内容、落款” 的格式一样。3.1 HTTP 请求格式客户端怎么 “提需求”一个完整的 HTTP 请求由 4 部分组成请求行 → 请求 Header → 空行 → 请求 Body我们用 “登录表单提交” 的请求举例httpPOST /login HTTP/1.1 # 请求行方法 URL 版本 Host: www.example.com # Header服务器地址 Content-Type: application/x-www-form-urlencoded # HeaderBody的数据类型 Content-Length: 27 # HeaderBody的长度字节数 # 空行分隔Header和Body usernamezhangsanpasswd123456 # Body登录数据表单内容各部分详解请求行HTTP 请求的 “核心指令”方法请求的类型比如 GET/POST后面详解URL要访问的资源路径比如/login版本HTTP 的版本常用 HTTP/1.1支持长连接。请求 Header请求的 “附加信息”以 “键值” 格式存在常见的有Host告诉服务器要访问哪个域名比如多域名共享一个服务器时有用User-Agent告诉服务器客户端的 “身份”比如Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0表示 Windows10 的 Chrome 浏览器Referer告诉服务器 “我是从哪个页面跳过来的”比如从百度搜索跳转到知乎Referer 就是百度的 URL。空行必须存在用于分隔 Header 和 Body如果没有空行服务器会把 Body 当成 Header 的一部分解析出错。请求 Body要传给服务器的 “具体数据”GET 请求的 Body 通常为空数据放在 URL 的查询字符串中POST 请求的 Body 用于传表单、文件等数据比如登录的账号密码。3.2 HTTP 响应格式服务器怎么 “回消息”服务器收到请求后会返回 HTTP 响应格式与请求对应状态行 → 响应 Header → 空行 → 响应 Body比如登录成功的响应httpHTTP/1.1 200 OK # 状态行版本 状态码 描述 Content-Type: text/html; charsetutf-8 # HeaderBody的数据类型HTML Content-Length: 128 # HeaderBody的长度 Set-Cookie: sessionidabc123; Path/ # Header设置Cookie记录登录状态 # 空行分隔Header和Body htmlbody登录成功/body/html # Body返回的网页内容各部分详解状态行服务器的 “处理结果”版本HTTP 版本与请求一致状态码3 位数字代表请求的处理状态比如 200 成功、404 找不到资源描述状态码的文字解释比如 OK、Not Found。响应 Header响应的 “附加信息”常见的有Content-Type告诉客户端 Body 的数据类型比如text/html是网页image/jpeg是图片Content-LengthBody 的长度客户端知道要读多少字节Location搭配 3xx 状态码使用告诉客户端 “跳转到新地址”比如重定向到首页Set-Cookie服务器给客户端 “发小纸条”记录状态比如登录后的 SessionID。空行分隔 Header 和 Body和请求同理。响应 Body服务器返回的 “实际内容”可能是 HTML网页、JSON接口数据、图片二进制数据等如果是 404 响应Body 就是 “找不到页面” 的提示网页。3.3 实战手写一个简单的 HTTP 服务器我们用 C 写一个极简的 HTTP 服务器功能是接收浏览器请求返回 “Hello World” 网页。通过代码理解 HTTP 响应的构建过程。代码实现#include iostream #include sys/socket.h #include netinet/in.h #include string.h #include unistd.h // 端口号选8080避免和默认80端口冲突 #define PORT 8080 // HTTP响应的内容状态行Header空行Body const char* RESPONSE HTTP/1.1 200 OK\r\n Content-Type: text/html; charsetutf-8\r\n Content-Length: 22\r\n \r\n h1Hello World!/h1; int main() { // 1. 创建socket相当于打开“通信管道” // 参数1AF_INETIPv4参数2SOCK_STREAMTCP参数30默认协议 // 返回值成功返回socket描述符非负整数失败返回-1 int listen_fd socket(AF_INET, SOCK_STREAM, 0); if (listen_fd -1) { perror(socket创建失败); return 1; } // 2. 绑定端口给“管道”分配一个“门牌号” struct sockaddr_in server_addr; memset(server_addr, 0, sizeof(server_addr)); server_addr.sin_family AF_INET; // IPv4 server_addr.sin_port htons(PORT); // 端口号转网络字节序 server_addr.sin_addr.s_addr INADDR_ANY; // 绑定所有网卡的IP // 参数1socket描述符参数2服务器地址结构体参数3结构体大小 // 返回值成功0失败-1 if (bind(listen_fd, (struct sockaddr*)server_addr, sizeof(server_addr)) -1) { perror(绑定端口失败); close(listen_fd); return 1; } // 3. 监听连接让“管道”处于“等待来电”状态 // 参数2等待队列的最大长度5个 // 返回值成功0失败-1 if (listen(listen_fd, 5) -1) { perror(监听失败); close(listen_fd); return 1; } std::cout HTTP服务器已启动访问http://127.0.0.1: PORT std::endl; while (true) { // 4. 接收客户端连接“接电话” struct sockaddr_in client_addr; socklen_t client_len sizeof(client_addr); // 参数2客户端地址结构体输出参数存客户端IP和端口参数3结构体大小指针 // 返回值成功返回新的socket描述符与该客户端通信失败返回-1 int conn_fd accept(listen_fd, (struct sockaddr*)client_addr, client_len); if (conn_fd -1) { perror(接收连接失败); continue; } // 5. 读取客户端请求可选这里只打印请求内容 char buf[1024] {0}; // 参数2缓冲区参数3缓冲区大小参数40默认读取方式 // 返回值成功返回读取的字节数0表示客户端断开-1表示失败 ssize_t n recv(conn_fd, buf, sizeof(buf)-1, 0); if (n 0) { std::cout 收到客户端请求\n buf std::endl; } // 6. 发送HTTP响应给客户端“回消息” // 参数2响应内容参数3响应长度参数40默认发送方式 // 返回值成功返回发送的字节数失败返回-1 send(conn_fd, RESPONSE, strlen(RESPONSE), 0); // 7. 关闭连接“挂电话” close(conn_fd); } // 8. 关闭监听socket实际不会执行到这里因为while(true) close(listen_fd); return 0; }代码解释核心函数说明socket()创建 TCP 通信的 “管道”返回的listen_fd是 “监听用的管道”bind()给监听管道绑定端口8080让客户端能找到服务器listen()让管道进入 “监听状态”等待客户端连接accept()接收客户端连接返回conn_fd是 “与该客户端通信的管道”recv()读取客户端发送的 HTTP 请求这里只打印不解析send()发送 HTTP 响应提前拼接好状态行、Header、Bodyclose()关闭管道释放资源。运行步骤编译g http_server.cpp -o http_server启动./http_server访问浏览器输入http://127.0.0.1:8080会看到 “Hello World!” 的大标题。四、HTTP 方法不同的 “请求类型” 有什么用HTTP 定义了多种 “请求方法”用来告诉服务器 “我要做什么操作”最常用的是GET和POST其他方法PUT/DELETE 等多用于接口开发。4.1 GET 方法“我要获取资源”用途从服务器获取资源比如网页、图片、查询数据是最常用的方法。示例浏览器访问百度首页GET / HTTP/1.1/表示根路径即首页百度搜索 “HTTP”GET /s?wdHTTP HTTP/1.1参数wdHTTP放在 URL 的查询字符串中。特点数据在 URL 中参数跟在?后面用分隔比如?usernamezhangsanage20长度有限制URL 的长度通常不超过 2048 字节不适合传大量数据不安全参数会显示在地址栏不适合传敏感数据比如密码可缓存浏览器会缓存 GET 请求的结果比如静态图片下次访问直接读缓存。4.2 POST 方法“我要提交数据”用途向服务器提交数据比如登录表单、上传文件。示例登录表单提交POST /login HTTP/1.1数据放在请求 Body 中不在 URL 里Body 内容usernamezhangsanpasswd123456。特点数据在 Body 中参数不显示在地址栏适合传敏感数据长度无限制可以传大文件比如 100MB 的图片不安全但比 GET 私密数据虽然不在 URL 中但默认还是明文传输需要 HTTPS 加密不可缓存浏览器不会缓存 POST 请求的结果每次提交都是新操作。4.3 GET vs POST用 “登录” 举例对比假设我们有一个登录页面login.html表单代码如下html!-- POST方法提交 -- form action/login methodPOST 用户名input typetext nameusernamebr 密码input typepassword namepasswdbr button typesubmit登录/button /form若用 POST请求行POST /login HTTP/1.1请求 Bodyusernamezhangsanpasswd123456地址栏http://127.0.0.1:8080/login无参数隐私性好。若改成 GET请求行GET /login?usernamezhangsanpasswd123456 HTTP/1.1请求 Body空地址栏http://127.0.0.1:8080/login?usernamezhangsanpasswd123456参数暴露不安全。五、HTTP 状态码服务器的 “表情符号”状态码是服务器返回的 3 位数字用来告诉客户端 “请求处理得怎么样了”就像服务器的 “表情”——200 是 “微笑”成功404 是 “疑惑”找不到500 是 “难过”服务器出错。5.1 状态码分类按第一位数字分类含义常见状态码1xx信息提示临时响应100继续2xx成功200OK3xx重定向需要进一步操作301永久重定向、302临时重定向4xx客户端错误请求有问题404Not Found、403Forbidden权限不足5xx服务器错误服务器有问题500Internal Server Error、504Gateway Timeout网关超时5.2 最常用的 5 个状态码1200 OK请求成功场景服务器正常处理了请求返回了需要的资源示例访问百度首页服务器返回 200Body 是百度首页的 HTML。2404 Not Found资源不存在场景客户端访问了服务器上没有的资源示例访问http://www.taobao.com/a.html如果淘宝服务器没有a.html这个文件就会返回 404Body 是 “页面找不到” 的提示。3301 Moved Permanently永久重定向场景资源被永久移动到新地址以后请用新地址访问示例访问http://taobao.com会重定向到https://www.taobao.com状态码 301响应 Header 中有Location: https://www.taobao.com。4302 Found临时重定向场景资源临时移动到新地址下次可能还会变示例登录成功后临时重定向到首页Location: /index。5500 Internal Server Error服务器内部错误场景服务器处理请求时出错比如代码 bug、数据库连接失败示例访问一个 PHP 页面PHP 代码有语法错误服务器返回 500。5.3 实战实现 302 重定向修改之前的 HTTP 服务器代码让访问/redir时重定向到百度首页// 在while(true)循环中接收连接后添加 if (n 0) { std::cout 收到客户端请求\n buf std::endl; // 判断是否访问/redir if (strstr(buf, GET /redir HTTP/1.1) ! NULL) { // 302重定向响应Location指向百度 const char* REDIRECT_RESP HTTP/1.1 302 Found\r\n Location: https://www.baidu.com\r\n \r\n; send(conn_fd, REDIRECT_RESP, strlen(REDIRECT_RESP), 0); close(conn_fd); continue; } } // 其他情况返回Hello World send(conn_fd, RESPONSE, strlen(RESPONSE), 0);运行效果访问http://127.0.0.1:8080/redir浏览器会自动跳转到百度首页抓包能看到服务器返回 302 状态码和Location: https://www.baidu.com。六、HTTP Header隐藏的 “附加信息”Header 是 HTTP 请求 / 响应中的 “附加说明”以 “键值” 格式存在决定了数据如何传输、解析。我们重点讲几个最常用的 Header。6.1 Content-Type数据的 “身份证”告诉接收方 “Body 中的数据是什么类型”避免解析错误。常见值Content-Type 值含义示例场景text/html; charsetutf-8HTML 网页UTF-8 编码浏览器显示网页application/jsonJSON 格式数据接口返回数据比如登录状态application/x-www-form-urlencoded表单数据键值对POST 表单提交image/jpegJPEG 图片加载图片text/plain纯文本返回简单文本比如 “登录成功”示例服务器返回图片时Header 要加httpContent-Type: image/jpeg Content-Length: 10240 # 图片大小10KB6.2 Cookie 与 Set-Cookie解决 “无状态” 的关键HTTP 是无状态的服务器记不住客户端这时候需要 “Cookie”—— 服务器通过Set-Cookie给客户端发 “小纸条”客户端下次请求时用Cookie带上 “小纸条”服务器就能识别客户端了。工作流程客户端第一次登录客户端发送登录请求POST /loginBody 是账号密码服务器验证成功返回响应 HeaderSet-Cookie: sessionidabc123; Path/浏览器收到后把sessionidabc123保存在本地 Cookie 文件中。客户端第二次访问客户端发送请求GET /index自动在 Header 中加Cookie: sessionidabc123服务器读取sessionidabc123查询到对应的用户信息知道 “你是刚才登录的张三”不用重新登录。实战设置 Cookie修改服务器代码返回响应时加Set-Cookieconst char* RESPONSE HTTP/1.1 200 OK\r\n Content-Type: text/html; charsetutf-8\r\n Content-Length: 30\r\n Set-Cookie: usernamezhangsan; Max-Age3600\r\n // Cookie有效期1小时 \r\n h1已设置Cookie刷新页面试试/h1;效果访问http://127.0.0.1:8080浏览器会保存usernamezhangsan的 Cookie刷新页面请求 Header 中会自动带上Cookie: usernamezhangsan打开浏览器 “开发者工具”→“应用”→“Cookie”能看到这个 Cookie。6.3 Connection长连接 vs 短连接控制客户端与服务器的连接是否保持Connection: close短连接默认 HTTP/1.0每次请求后断开连接Connection: keep-alive长连接默认 HTTP/1.1请求后保持连接下次请求不用重新建立。长连接的好处比如浏览一个有 10 张图片的网页短连接需要建立 11 次连接1 次 HTML10 次图片长连接只需要 1 次连接大大节省时间和资源。七、HTTPS更安全的 “HTTP”HTTP 的缺点是明文传输—— 数据在网络中传输时任何人都能通过抓包工具看到比如账号密码、支付信息。为了解决这个问题就有了HTTPSHTTP Secure。7.1 HTTPS 是什么—— HTTP 加密层HTTPS 不是新协议而是在 HTTP 和 TCP 之间加了一层SSL/TLS 加密层客户端发送数据HTTP 数据 → SSL/TLS 加密 → TCP 传输服务器接收数据TCP 数据 → SSL/TLS 解密 → HTTP 数据。这样数据在网络中传输时是 “密文”即使被抓包也看不到原始内容。7.2 为什么需要 HTTPS—— 防止 “中间人攻击”没有 HTTPS 时运营商或黑客可能 “劫持” 数据你点击 “下载 QQ”运营商把下载链接改成 “下载 QQ 浏览器”你输入银行卡号黑客抓包后偷走信息。有了 HTTPS数据被加密劫持者看不到原始内容也无法篡改篡改后解密会失败。7.3 HTTPS 的核心证书与加密HTTPS 的安全依赖两个关键技术证书和混合加密。1证书证明服务器 “身份合法”服务器要使用 HTTPS需要向CA 机构比如 Symantec、Let’s Encrypt申请 “数字证书”证书包含服务器的域名、公钥CA 机构的签名用 CA 的私钥加密防止证书被篡改。客户端浏览器收到证书后会验证证书是否在有效期内证书的 CA 机构是否在浏览器的 “信任列表” 中浏览器内置了很多权威 CA 的公钥证书的签名是否合法用 CA 的公钥解密签名对比证书内容的哈希值确认没被篡改。2混合加密兼顾安全与速度HTTPS 用 “非对称加密” 协商 “对称加密密钥”再用 “对称加密” 传输数据非对称加密有公钥和私钥公钥加密的内容只有私钥能解密慢但安全服务器把公钥放在证书中发给客户端客户端生成一个 “对称加密密钥”用服务器的公钥加密后发给服务器服务器用自己的私钥解密得到 “对称加密密钥”。对称加密用同一个密钥加密和解密快适合大量数据后续客户端和服务器的所有数据都用这个 “对称加密密钥” 加密传输。7.4 HTTP vs HTTPS关键区别对比项HTTPHTTPS端口80443加密明文传输SSL/TLS 加密证书不需要需要 CA 证书速度快无加密开销稍慢有加密解密开销安全不安全安全地址栏标识无 “锁” 图标有绿色 “锁” 图标八、总结HTTP 是互联网的 “通用语言”这篇博客从基础到实战讲解了HTTP 是什么客户端与服务器的通信协议无连接、无状态URL 结构从协议到片段标识符特殊字符需要 urlencode请求响应格式4 部分组成空行是关键分隔方法与状态码GET 获取、POST 提交200 成功、404 找不到Header 作用Content-Type 定义数据类型Cookie 解决无状态HTTPS 安全加密层 证书防止数据泄露和篡改。-------------------------------------------------------------------------------------------------------------------------------通过实战代码我们亲手实现了简单 HTTP 服务器、302 重定向、设置 Cookie相信你已经对 HTTP 有了直观的理解。下次浏览网页时不妨打开 “开发者工具”看看请求和响应的细节 —— 你会发现原来背后都是这些知识点在工作

相关新闻