
1. 什么是 httplibhttplib是一个用 C11 写的 HTTP 库只有一个头文件httplib.h不需要安装任何其他东西就能用。它主要提供四个核心类Server用来搭建服务器让别人来访问你的程序。Client用来当客户端让你的程序去访问别人的网站或 API。Request存着请求信息比如谁来了、带了什么参数。Response用来设置要返回给客户端的内容。下面我们通过一个个例子把这四个类和 Get、Post、Put、Delete 四种请求方式全部讲清楚。2. 准备工作下载 httplib下载httplib.h放到你的项目文件夹里打开 https://github.com/yhirose/cpp-httplib找到httplib.h下载下来放到你的 C 项目文件夹中然后在代码里写#include httplib.h就能用了。3. Server 类 Get 请求搭建一个服务器我们先写一个最简单的服务器当浏览器访问/hello时返回 Hello World!。#include iostream #include httplib.h int main() { // Server 类 // Server 是用来创建 HTTP 服务器的类 // svr 是 Server 的一个对象实例 httplib::Server svr; // Get() 方法 // Get() 是 Server 类的成员函数 // 作用注册一个 GET 请求的处理方式 // 参数1路径字符串比如 /hello // 参数2回调函数当有人访问这个路径时执行 // 回调函数的两个参数 // req —— Request 对象存着浏览器发来的信息 // res —— Response 对象用来设置返回给浏览器的内容 svr.Get(/hello, [](const httplib::Requestamp; req, httplib::Responseamp; res) { // Response 类 // Response 是用来设置 HTTP 响应的类 // set_content() 是 Response 类的成员函数 // 作用设置返回的内容 // 参数1要返回的字符串 // 参数2内容类型text/plain 表示纯文本 res.set_content(Hello World!, text/plain); }); // listen() 方法 // listen() 是 Server 类的成员函数 // 作用启动服务器开始监听 // 参数1IP 地址localhost 表示只允许本机访问 // 参数2端口号8080 是常用测试端口 std::cout lt;lt; 服务器已启动访问 http://localhost:8080/hello lt;lt; std::endl; svr.listen(localhost, 8080); return 0; }运行步骤用支持 C11 的编译器编译g 加-stdc11运行程序浏览器打开http://localhost:8080/hello页面上显示Hello World!4. Client 类 Get 请求访问一个网站现在用 Client 类写一个程序去访问百度首页把网页内容下载下来。#include iostream #include httplib.h int main() { // Client 类 // Client 是用来发送 HTTP 请求的类 // 构造函数参数要访问的网站地址带协议 httplib::Client cli(https://www.baidu.com); // Get() 方法Client 版 // Get() 是 Client 类的成员函数 // 作用发送 GET 请求 // 参数路径/ 表示首页 // 返回值一个智能指针指向 Response 对象 // 如果请求失败这个指针为空nullptr auto res cli.Get(/); // Request 类隐含 // 当我们调用 cli.Get(/) 时httplib 内部会自动创建一个 Request 对象 // 把路径 / 等信息放进去然后发送出去 // 我们不需要手动创建 Request 对象 // Response 类 // res 是一个指向 Response 对象的智能指针 // res-gt;statusHTTP 状态码int 类型 // 200 成功404 找不到500 服务器错误 // res-gt;body服务器返回的正文内容string 类型 if (res amp;amp; res-gt;status 200) { std::cout lt;lt; 请求成功网页内容长度 lt;lt; res-gt;body.length() lt;lt; 字节 lt;lt; std::endl; std::cout lt;lt; 前100个字符 lt;lt; res-gt;body.substr(0, 100) lt;lt; std::endl; } else { std::cout lt;lt; 请求失败 lt;lt; std::endl; } return 0; }5. Server 类 Post 请求接收用户提交的数据服务器用 Post 接收用户发来的数据比如表单、JSON。#include iostream #include httplib.h int main() { httplib::Server svr; // Post() 方法 // Post() 是 Server 类的成员函数 // 作用注册一个 POST 请求的处理方式 // 参数和 Get() 一样路径 回调函数 svr.Post(/submit, [](const httplib::Requestamp; req, httplib::Responseamp; res) { // Request 类 // req.bodyRequest 类的成员变量 // 类型std::string // 作用存着客户端 POST 过来的原始数据字符串 std::string data req.body; std::cout lt;lt; 收到数据 lt;lt; data lt;lt; std::endl; // 返回响应 res.set_content(收到你的数据了, text/plain; charsetutf-8); }); std::cout lt;lt; 服务器已启动请用 Post 方式访问 http://localhost:8080/submit lt;lt; std::endl; svr.listen(localhost, 8080); return 0; }6. Client 类 Post 请求向服务器发送数据用 Client 的 Post 方法向服务器发送数据。#include iostream #include httplib.h int main() { httplib::Client cli(http://localhost:8080); // Post() 方法Client 版 // Post() 是 Client 类的成员函数 // 作用发送 POST 请求 // 参数1路径 // 参数2要发送的数据字符串 // 参数3内容类型text/plain 表示纯文本 auto res cli.Post(/submit, 你好这是我要提交的数据, text/plain); if (res) { std::cout lt;lt; 服务器返回 lt;lt; res-gt;body lt;lt; std::endl; } else { std::cout lt;lt; 请求失败 lt;lt; std::endl; } return 0; }7. Server 类 Put 请求更新资源Put 通常用来更新已有的数据。#include iostream #include httplib.h int main() { httplib::Server svr; // Put() 方法 // Put() 是 Server 类的成员函数 // 作用注册一个 PUT 请求的处理方式 svr.Put(/user/update, [](const httplib::Requestamp; req, httplib::Responseamp; res) { // req.body 里存着客户端发来的更新数据 std::cout lt;lt; 收到更新数据 lt;lt; req.body lt;lt; std::endl; res.set_content(更新成功, text/plain; charsetutf-8); }); svr.listen(localhost, 8080); return 0; }8. Client 类 Put 请求发送更新数据#include iostream #include httplib.h int main() { httplib::Client cli(http://localhost:8080); // Put() 方法Client 版 // Put() 是 Client 类的成员函数 // 参数和 Post() 一样路径 数据 内容类型 auto res cli.Put(/user/update, {\name\:\张三\,\age\:25}, application/json); if (res) { std::cout lt;lt; 服务器返回 lt;lt; res-gt;body lt;lt; std::endl; } return 0; }9. Server 类 Delete 请求删除资源Delete 用来删除数据。#include iostream #include httplib.h int main() { httplib::Server svr; // Delete() 方法 // Delete() 是 Server 类的成员函数 // 作用注册一个 DELETE 请求的处理方式 svr.Delete(/user/123, [](const httplib::Requestamp; req, httplib::Responseamp; res) { // req.path 存着请求的完整路径 std::cout lt;lt; 收到删除请求路径 lt;lt; req.path lt;lt; std::endl; res.set_content(删除成功, text/plain; charsetutf-8); }); svr.listen(localhost, 8080); return 0; }10. Client 类 Delete 请求发送删除请求#include iostream #include httplib.h int main() { httplib::Client cli(http://localhost:8080); // Delete() 方法Client 版 // Delete() 是 Client 类的成员函数 // 参数路径 auto res cli.Delete(/user/123); if (res) { std::cout lt;lt; 服务器返回 lt;lt; res-gt;body lt;lt; std::endl; } return 0; }11. 四个核心类总结类名作用常用成员Server创建 HTTP 服务器Get()、Post()、Put()、Delete()、listen()Client发送 HTTP 请求Get()、Post()、Put()、Delete()Request存着请求信息body请求体、path路径、method请求方法Response设置响应内容set_content()、status状态码、body响应体12. 四种请求方法总结方法Server 端作用Client 端作用Get处理获取数据的请求发送获取数据的请求Post处理创建/提交数据的请求发送创建/提交数据的请求Put处理更新数据的请求发送更新数据的请求Delete处理删除数据的请求发送删除数据的请求13. 常见问题问题原因解决方法找不到 httplib.h头文件路径不对把 httplib.h 放到和 cpp 文件同一个文件夹端口被占用8080 已被其他程序使用换一个端口比如svr.listen(localhost, 8081)中文乱码没指定编码在 set_content 里加上; charsetutf-814. 完整示例一个能增删改查的服务器把上面学到的串起来写一个完整的待办事项管理程序#include iostream #include map #include httplib.h int main() { httplib::Server svr; std::mapint, std::string todos; // 用 map 存数据 int nextId 1; // 获取所有待办事项Get svr.Get(/todos, [amp;](const httplib::Requestamp;, httplib::Responseamp; res) { std::string result; for (const autoamp; [id, text] : todos) { result std::to_string(id) : text \n; } res.set_content(result, text/plain; charsetutf-8); }); // 创建待办事项Post svr.Post(/todos, [amp;](const httplib::Requestamp; req, httplib::Responseamp; res) { int id nextId; todos[id] req.body; res.set_content(创建成功ID: std::to_string(id), text/plain; charsetutf-8); }); // 更新待办事项Put svr.Put(/todos, [amp;](const httplib::Requestamp; req, httplib::Responseamp; res) { // 假设数据格式是 id:新内容 size_t pos req.body.find(:); if (pos ! std::string::npos) { int id std::stoi(req.body.substr(0, pos)); std::string text req.body.substr(pos 1); todos[id] text; res.set_content(更新成功, text/plain; charsetutf-8); } else { res.set_content(格式错误, text/plain; charsetutf-8); } }); // 删除待办事项Delete svr.Delete(R(/todos/(\d)), [amp;](const httplib::Requestamp; req, httplib::Responseamp; res) { int id std::stoi(req.matches[1]); if (todos.erase(id)) { res.set_content(删除成功, text/plain; charsetutf-8); } else { res.status 404; res.set_content(没找到这个 ID, text/plain; charsetutf-8); } }); std::cout lt;lt; 待办事项 API 运行在 http://localhost:8080 lt;lt; std::endl; svr.listen(localhost, 8080); return 0; }用 Client 测试一下#include iostream #include httplib.h int main() { httplib::Client cli(http://localhost:8080); // 创建两个待办事项 cli.Post(/todos, 写作业, text/plain); cli.Post(/todos, 买菜, text/plain); // 获取所有待办事项 auto res cli.Get(/todos); if (res) std::cout lt;lt; 当前待办事项\n lt;lt; res-gt;body lt;lt; std::endl; // 更新 ID 为 1 的事项 cli.Put(/todos, 1:写数学作业, text/plain); // 删除 ID 为 2 的事项 cli.Delete(/todos/2); // 再次获取 res cli.Get(/todos); if (res) std::cout lt;lt; 修改后\n lt;lt; res-gt;body lt;lt; std::endl; return 0; }15. 总结到这里你已经学会了 httplib 最核心的四个类和四种请求方法Server 类用Get()、Post()、Put()、Delete()注册路由用listen()启动服务器。Client 类用Get()、Post()、Put()、Delete()发送请求。Request 类通过req.body获取请求数据req.path获取路径。Response 类用res.set_content()返回内容用res.status设置状态码。下一步你可以试着用 httplib 写一个自己的小项目比如一个留言板、一个文件分享工具或者一个简单的聊天室后端。