news 2026/4/16 7:23:43

使用cpp-httplib发布静态文件服务

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
使用cpp-httplib发布静态文件服务

1. 引言

静态文件(Static Files)是指那些内容在服务器上预先写好、不会随请求动态改变的文件,例如:

  • HTML 页面(如 index.html)
  • CSS 样式表(如 style.css)
  • JavaScript 脚本(如 app.js)
  • 图片(如 logo.png, photo.jpg)
  • 字体、图标、PDF、音视频等

静态文件服务(Static File Serving)是指 HTTP 服务器能够接收客户端(如浏览器)对某个路径的请求,并自动从本地文件系统中找到对应文件,将其内容返回给客户端。例如:

  • 用户访问 http://example.com/style.css
  • 服务器自动去磁盘找 ./www/style.css
  • 读取文件内容,设置正确的 Content-Type: text/css
  • 把文件原样返回给浏览器

这个过程无需写任何业务逻辑代码,由 HTTP 服务器框架自动完成。

一个通用的 HTTP 服务器框架通常会提供静态文件服务功能,因为:

  • 实现简单:读文件 + 设置 MIME 类型即可;
  • 用途广泛:极大简化小型项目部署;
  • 开发体验好:不用额外起 Nginx 就能跑完整 Web 应用;
  • 符合 HTTP 本质:HTTP 最初就是为传输静态文档设计的(超文本传输协议)。

2. 实例

使用 cpp-httplib 发布静态文件服务非常简单:

/* by 01130.hk - online tools website : 01130.hk/zh/regexdso.html */ #include <httplib.h> #include <iostream> #include <string> using namespace std; int main() { httplib::Server svr; svr.set_mount_point("/public", "D:/Work/HttpServer/public"); std::cout << "Server listening on http://0.0.0.0:8080/public\n"; svr.listen("0.0.0.0", 8080); return 0; }

D:/Work/HttpServer/public这个目录中笔者放置了一些文件:

那么可以在浏览器通过 URL 地址http://127.0.0.1:8080/public/最小二乘问题详解1:线性最小二乘/meta.json访问到具体的文件内容:

那么是不是所有的文件都支持访问并且加载显示呢?这取决于 HTTP 服务器(cpp-httplib)对文件扩展名与 MIME 类型的映射能力:

扩展名MIME 类型扩展名MIME 类型
csstext/cssmpgaaudio/mpeg
csvtext/csvwebaaudio/webm
txttext/plainwavaudio/wave
vtttext/vttotffont/otf
html, htmtext/htmlttffont/ttf
apngimage/apngwofffont/woff
avifimage/avifwoff2font/woff2
bmpimage/bmp7zapplication/x-7z-compressed
gifimage/gifatomapplication/atom+xml
pngimage/pngpdfapplication/pdf
svgimage/svg+xmlmjs, jstext/javascript
webpimage/webpjsonapplication/json
icoimage/x-iconrssapplication/rss+xml
tifimage/tifftarapplication/x-tar
tiffimage/tiffxhtml, xhtapplication/xhtml+xml
jpeg, jpgimage/jpegxsltapplication/xslt+xml
mp4video/mp4xmlapplication/xml
mpegvideo/mpeggzapplication/gzip
webmvideo/webmzipapplication/zip
mp3audio/mp3wasmapplication/wasm

3. 扩展

set_mount_point是 cpp-httplib 用于发布静态文件服务的接口,将设置的目录挂载到 HTTP Get 请求。如果将代码写的更加本质一点,就是读取相应的数据,将数据填充到 Get 请求返回:

/* by 01130.hk - online tools website : 01130.hk/zh/regexdso.html */ #include <httplib.h> #include <filesystem> // C++17 #include <fstream> #include <iostream> #include <nlohmann/json.hpp> #include <string> using namespace std; namespace fs = std::filesystem; // 辅助函数:根据文件扩展名返回 MIME 类型 std::string get_mime_type(const std::string& filename) { if (filename.ends_with(".md")) { return "text/markdown; charset=utf-8"; } else if (filename.ends_with(".json")) { return "application/json; charset=utf-8"; } else if (filename.ends_with(".txt")) { return "text/plain; charset=utf-8"; } // 默认 fallback return "application/octet-stream"; } int main() { httplib::Server svr; std::u8string docRoot = u8"D:/Work/HttpServer/public/最小二乘问题详解1:线性最小二乘"; // 路由:GET /files/<filename> svr.Get(R"(/files/([^/]+))", [&](const httplib::Request& req, httplib::Response& res) { // 提取文件名(来自正则捕获组) std::string filename = req.matches[1]; std::u8string u8Filename(filename.begin(), filename.end()); // 安全检查:防止路径穿越(如 ../../etc/passwd) if (filename.find("..") != std::string::npos || filename.empty()) { res.status = 400; res.set_content(R"({"error": "Invalid filename"})", "application/json"); return; } // 构建完整路径 fs::path filepath = fs::path(docRoot) / u8Filename; // 检查文件是否存在且是普通文件 if (!fs::exists(filepath) || !fs::is_regular_file(filepath)) { res.status = 404; res.set_content(R"({"error": "File not found"})", "application/json"); return; } // 读取文件内容 std::ifstream file(filepath, std::ios::binary); if (!file) { res.status = 500; res.set_content(R"({"error": "Failed to read file"})", "application/json"); return; } std::string content((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>()); // 设置 Content-Type std::string mime = get_mime_type(filename); res.set_content(content, mime); }); std::cout << "Server listening on http://0.0.0.0:8080/files/<filename>\n"; svr.listen("0.0.0.0", 8080); return 0; }

如果我们在浏览器地址访问http://127.0.0.1:8080/files/最小二乘问题详解1:线性最小二乘.md,就可以看到最小二乘问题详解1:线性最小二乘.md这个文件的内容:

这是因为这里将 .md 文件的 MIME 设置成了 text/markdown,浏览器会按照文本格式显示 .md 文件的内容。而在set_mount_point接口中,由于不识别 .md 格式类型,MIME 类型会回退回 application/octet-stream ,也就是二进制文件/未知类型,浏览器会强制下载。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/14 23:14:48

YOLO镜像预装PyTorch环境,省去繁琐配置步骤

YOLO镜像预装PyTorch环境&#xff0c;省去繁琐配置步骤 在工业视觉系统部署现场&#xff0c;工程师最怕听到的一句话是什么&#xff1f;——“环境跑不起来”。明明模型已经调好&#xff0c;代码也能在开发机上流畅运行&#xff0c;可一到边缘设备上就报错&#xff1a;CUDA not…

作者头像 李华
网站建设 2026/4/14 7:44:08

YOLOv5到YOLOv8迁移指南:如何平滑升级你的检测系统?

YOLOv5到YOLOv8迁移指南&#xff1a;如何平滑升级你的检测系统&#xff1f; 在工业质检线上&#xff0c;一个微小的焊点缺陷可能引发整批PCB板报废&#xff1b;在智能安防场景中&#xff0c;一次漏检就可能导致安全隐患。面对这些高要求的视觉任务&#xff0c;目标检测模型的选…

作者头像 李华
网站建设 2026/4/11 1:23:23

【AI白皮书】AI网关

6.1 网关的演进历程 是什么在推动软件架构的演进呢&#xff1f;业务规模。业务从互联网、移动互联网以及即将到来的万物互联&#xff0c;其规模仍然在高速增长&#xff0c;也就意味着软件架构的复杂度也会越来越高&#xff0c;网关的特性也会越来越多。越来越复杂、越来越智能。…

作者头像 李华
网站建设 2026/4/14 20:39:32

YOLO模型支持NCNN推理框架,安卓端高效部署

YOLO模型支持NCNN推理框架&#xff0c;安卓端高效部署 在如今的移动AI浪潮中&#xff0c;越来越多的应用开始要求设备具备“看得懂世界”的能力——从智能门铃识别人形&#xff0c;到工厂巡检机器人自动发现异常&#xff0c;视觉感知正从云端走向终端。而在这背后&#xff0c;一…

作者头像 李华
网站建设 2026/4/16 0:19:54

YOLO目标检测模型云端部署最佳实践:节省50%算力成本

YOLO目标检测模型云端部署最佳实践&#xff1a;节省50%算力成本 在智能制造、自动驾驶和城市级智能安防系统加速落地的今天&#xff0c;AI视觉应用早已从“能看懂图像”迈向“必须实时响应”的阶段。尤其是视频流分析这类高并发场景——比如一个智慧园区接入数百路摄像头进行周…

作者头像 李华
网站建设 2026/4/10 17:32:15

YOLO实时检测如何实现毫秒级响应?GPU并行计算揭秘

YOLO实时检测如何实现毫秒级响应&#xff1f;GPU并行计算揭秘 在智能工厂的高速生产线上&#xff0c;摄像头每秒捕捉上百帧图像&#xff0c;系统必须在几十毫秒内判断产品是否存在划痕、缺件或装配偏差。任何延迟都可能导致成千上万个缺陷品流入下一环节——这正是现代工业对视…

作者头像 李华