当前位置: 首页 > news >正文

从后端获取数据传输到前端进行显示(cpp-httplib+Vditor+Handlebars)

1. 引言

在之前的文章中,笔者实现了一个渲染 Markdown 格式文章的网页前端 Vite 项目(参看《给 Markdown 渲染网页增加一个目录组件(Vite+Vditor+Handlebars)》),以及一个支持 Markdown格式数据的静态文件服务的后端项目(参看《使用cpp-httplib发布静态文件服务》)。在这里,就将前端与后端打通,通过 cpp-httplib 提供的 API 接口动态返回 Markdown 文章数据,由前端 Vite 项目利用 Handlebars 模板与 Vditor 渲染引擎完成展示与交互。

2. 实现

2.1 后端

JSON 是 HTTP 传输中事实上的标准数据格式,尤其是在现代 Web API(特别是 RESTful API)中,因此我们将后端的接口改成返回 JSON 格式数据的接口。按照 RESTful API 风格,命名为 /api/v1/post,使用 HTTP 的 Get 方法。具体代码如下:

#include <httplib.h>#include <filesystem>
#include <fstream>
#include <iostream>
#include <nlohmann/json.hpp>
#include <string>#include "BlogData.h"using namespace std;
using namespace nlohmann;
namespace fs = std::filesystem;int main() {httplib::Server svr;std::u8string docRoot =u8"D:/Work/HttpServer/public/最小二乘问题详解1:线性最小二乘";svr.Get("/api/v1/post",[&](const httplib::Request& req, httplib::Response& res) {DataTransfer::BlogData blogData;{fs::path blogMetaJsonPath = fs::path(docRoot) / "meta.json";nlohmann::json blogMetaJson;ifstream infile(blogMetaJsonPath);infile >> blogMetaJson;blogData.blogMeta = blogMetaJson;}{fs::path blogContentPath =fs::path(docRoot) / u8"最小二乘问题详解1:线性最小二乘.md";std::ifstream file(blogContentPath, std::ios::binary);std::string content((std::istreambuf_iterator<char>(file)),std::istreambuf_iterator<char>());blogData.content = std::move(content);}// 构造响应 JSONjson response_data = blogData;// 设置响应res.set_header("Access-Control-Allow-Origin","http://127.0.0.1:8000");  // 允许跨域res.set_content(response_data.dump(), "application/json");});std::cout << "Server listening on http://127.0.0.1:8080\n";svr.listen("0.0.0.0", 8080);return 0;
}

这段代码的实现非常简单,分别读取元数据 meta.json 和 文章内容 最小二乘问题详解1:线性最小二乘.md 文件,组织成 JSON 格式,设置到 HTTP 响应的内容中并且返回。其中,用到 nlohmann/json 对 结构体对象序列化和反序列化(参考《C++中JSON序列化和反序列化的实现》)。

另外需要注意的就是跨域问题。由于前端项目与后端项目是分离的,因此它们处在不同的域中,前端要请求后端的资源,就会发生跨域问题。解决办法就是在 HTTP 的响应头中设置允许跨域的键和值:

res.set_header("Access-Control-Allow-Origin", "http://127.0.0.1:8000");  // 允许跨域

2.2 前端

前端的修改就简单多了,只需要修改获取远端数据的接口就可以了:

const response = await fetch("http://127.0.0.1:8080/api/v1/post");
if (!response.ok) {throw new Error("网络无响应");
}
const blogData = await response.json();
//...

其实这也是前后端分离的优势,后端提供数据资源的获取,前端则负责数据的可视化。最终的效果如下所示:

从后端访问数据到前端进行展示

3. 其他

以上就是一个最简单的前后端分离 Web 项目。任何复杂功能都可以在此基础上进行扩展,只需搭配相应的架构设计,以更好地支持具体业务需求。

实现代码

http://www.rkmt.cn/news/198305.html

相关文章:

  • 游戏NPC语音生成:VoxCPM-1.5-TTS-WEB-UI让角色说话更自然
  • 湖北神农架:野人传说伴随原始森林的风吹草动
  • 马来西亚多元文化:三种主要语言自由切换播报
  • 柬埔寨吴哥窟黎明:第一缕阳光照耀时的静谧
  • 【高并发系统设计必修课】:Java 24结构化并发异常处理的5大最佳实践
  • 边疆地区教育公平:少数民族学生享受优质语音资源
  • 奥地利音乐之都:维也纳新年音乐会AI伴奏
  • 元宇宙语音交互基石:VoxCPM-1.5-TTS-WEB-UI构建沉浸式对话体验
  • 你还在手动强转?JDK 23 instanceof int让类型判断变得如此智能!
  • 远古祭祀仪式重现:宗教学者研究早期文明形态
  • 2026国内维生素 B 族排名出炉!中老年人、熬夜党、上班族必看的高性价比清单 - 博客万
  • AI伦理讨论焦点:VoxCPM-1.5-TTS-WEB-UI能否被滥用于伪造录音?
  • 深入解析:49、【Ubuntu】【Gitlab】拉出内网 Web 服务:http.server 单/多线程分析(一)
  • ZGC分代模式揭秘:如何实现亚毫秒级停顿与高效内存管理
  • 微PE官网同源技术社区推荐:AI语音新星VoxCPM-1.5-TTS-WEB-UI发布
  • GitHub镜像网站同步更新:VoxCPM-1.5-TTS-WEB-UI开源语音模型上线
  • Asyncio事件监听机制详解:5个关键点让你避开90%的陷阱
  • 基于YOLOv8的道路坑洼识别检测系统(YOLOv8深度学习+YOLO数据集+UI界面+Python项目源码+模型)
  • 火星殖民地设想:第一批移民将携带语音数据库
  • Java虚拟线程时代来临(线程池配置终极指南)
  • 奥运会开幕式解说:AI同时提供数十种语言服务
  • Python和C#x2B;#x2B;数据结构学习笔记
  • 题解:AT_abc257_d [ABC257D] Jumping Takahashi 2
  • Python如何精准控制3D场景视角?这4个库你必须了解
  • 为什么你的模型训练越来越慢?根源可能出在多模态存储结构上
  • 告别卡顿视角!Python 3D渲染中的平滑控制优化策略(性能提升90%)
  • 题解:B4350 [信息与未来 2025] 美味水果
  • 社交软件动态播报:好友更新内容自动语音朗读
  • 题解:P5663 [CSP-J2019] 加工零件
  • 广东广州早茶:茶楼伙计穿梭间喊出地道粤语