C++用Crow实现一个简单的Web程序,实现动态页面,向页面中输入数据并展示

Crow是一个轻量级、快速的C++微框架,用于构建Web应用程序和RESTful API。

将处理前端页面的POST请求以添加数据的逻辑添加到 `/submit` 路由中,并添加了一个新的路由 `/` 用于返回包含输入框、按钮和表格的完整页面。当用户向表格添加数据时,JavaScript会发送POST请求到 `/submit` 路由,后端会处理数据并将其添加到数据向量中。另外,当页面加载时,JavaScript会发送GET请求到 `/table` 路由,以获取更新后的表格数据 。

#include <crow.h>
#include <sstream>
#include <string>
#include <vector>

std::vector<std::string> data;

int main() {
    crow::SimpleApp app;

    // 添加数据的页面
    CROW_ROUTE(app, "/")
        ([] {
        std::ostringstream os;
        os << "<html><body>";
        os << "<h1>Add Data to Table</h1>";
        os << "<input type='text' id='dataInput' placeholder='Enter data'>";
        os << "<button onclick='addData()'>Add Data</button>";
        os << "<table id='dataTable'>";
        os << "<tr><th>Data</th></tr>";
        for (const auto& item : data) {
            os << "<tr><td>" << item << "</td></tr>";
        }
        os << "</table>";
        os << "<script>";
        os << "function addData() {";
        os << "var input = document.getElementById('dataInput');";
        os << "var data = input.value;";
        os << "var xhr = new XMLHttpRequest();";
        os << "xhr.open('POST', '/submit', true);";
        os << "xhr.setRequestHeader('Content-Type', 'application/json');";
        os << "xhr.send(JSON.stringify({ data: data }));";
        os << "xhr.onload = function() {";
        os << "if (xhr.status === 200) {";
        os << "input.value = '';";
        os << "fetchData();";
        os << "}";
        os << "};";
        os << "}";
        os << "function fetchData() {";
        os << "var table = document.getElementById('dataTable');";
        os << "var xhr = new XMLHttpRequest();";
        os << "xhr.open('GET', '/table', true);";
        os << "xhr.send();";
        os << "xhr.onload = function() {";
        os << "if (xhr.status === 200) {";
        os << "table.innerHTML = '<tr><th>Data</th></tr>' + xhr.responseText;";
        os << "}";
        os << "};";
        os << "}";
        os << "fetchData();";
        os << "</script>";
        os << "</body></html>";
        return crow::response(os.str());
            });

    // 处理提交数据的路由
    CROW_ROUTE(app, "/submit")
        .methods("POST"_method)
        ([](const crow::request& req) {
        crow::json::rvalue json = crow::json::load(req.body);
        if (!json) {
            return crow::response(400);
        }

        std::string dataValue = json["data"].s();
        data.push_back(dataValue);

        return crow::response(200);
            });

    // 返回更新后的表格数据
    CROW_ROUTE(app, "/table")
        ([] {
        std::ostringstream os;
        for (const auto& item : data) {
            os << "<tr><td>" << item << "</td></tr>";
        }
        return crow::response(os.str());
            });

    app.port(8080).multithreaded().run();
}

运行效果: 

嗯....好吧,一般人是不会在后端代码里面嵌套这么一大坨html代码的对吧,所有我们将它们分离开来。

将html和js代码提取到index.html文件中。

<!DOCTYPE html>
<html>
<head>
    <title>Data Table</title>
</head>
<body>
    <h1>Add Data to Table</h1>
    <input type='text' id='dataInput' placeholder='Enter data'>
    <button onclick='addData()'>Add Data</button>
    <table id='dataTable'>
        <tr><th>Data</th></tr>
    </table>
    <script>
        function addData() {
            var input = document.getElementById('dataInput');
            var data = input.value;
            var xhr = new XMLHttpRequest();
            xhr.open('POST', '/submit', true);
            xhr.setRequestHeader('Content-Type', 'application/json');
            xhr.send(JSON.stringify({ data: data }));
            xhr.onload = function () {
                if (xhr.status === 200) {
                    input.value = '';
                    fetchData();
                }
            };
        }
        function fetchData() {
            var table = document.getElementById('dataTable');
            var xhr = new XMLHttpRequest();
            xhr.open('GET', '/table', true);
            xhr.send();
            xhr.onload = function () {
                if (xhr.status === 200) {
                    table.innerHTML = '<tr><th>Data</th></tr>' + xhr.responseText;
                }
            };
        }
        fetchData();
    </script>
</body>
</html>

cpp文件中的代码修改如下。 

#include <crow.h>
#include <fstream>
#include <streambuf>
#include <string>
#include <vector>

std::vector<std::string> data;

int main() {
    crow::SimpleApp app;

    // 提供HTML文件
    CROW_ROUTE(app, "/")
        ([] {
        std::ifstream t("index.html");
        std::string html((std::istreambuf_iterator<char>(t)), std::istreambuf_iterator<char>());
        crow::response response(html);
        response.add_header("Content-Type", "text/html");
        return response;
            });

    // 处理提交数据的路由
    CROW_ROUTE(app, "/submit")
        .methods("POST"_method)
        ([](const crow::request& req) {
        crow::json::rvalue json = crow::json::load(req.body);
        if (!json) {
            return crow::response(400);
        }

        std::string dataValue = json["data"].s();
        data.push_back(dataValue);

        return crow::response(200);
            });

    // 返回更新后的表格数据
    CROW_ROUTE(app, "/table")
        ([] {
        std::ostringstream os;
        for (const auto& item : data) {
            os << "<tr><td>" << item << "</td></tr>";
        }
        return crow::response(os.str());
            });

    app.port(8080).multithreaded().run();
}

如果在浏览器中访问 `http://localhost:8080` 时只看到HTML源代码而不是页面内容,而且状态码是200,这可能是因为浏览器没有正确解析HTML内容,一种可能的原因是浏览器接收到的数据的Content-Type头部不正确,导致浏览器将其视为纯文本而不是HTML。可以尝试在Crow应用程序中为返回的HTML内容设置正确的Content-Type头部。

可以达到相同的效果。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/746889.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

创新与责任并重!中国星坤连接器的可持续发展战略!

在当今全球化的商业环境中&#xff0c;企业的社会责任、技术创新和产品质量是企业可持续发展的三大支柱。中国星坤正是这样一家企业&#xff0c;它在电子连接技术领域以其卓越的技术创新、坚定的环保责任和严格的生产品控而著称。本文将深入探讨星坤科技如何通过其FAE技术团队的…

浏览器扩展V3开发系列之 chrome.contextMenus 右键菜单的用法和案例

【作者主页】&#xff1a;小鱼神1024 【擅长领域】&#xff1a;JS逆向、小程序逆向、AST还原、验证码突防、Python开发、浏览器插件开发、React前端开发、NestJS后端开发等等 chrome.contextMenus 允许开发者向浏览器的右键菜单添加自定义项。 在使用 chrome.contextMenus 之前…

CMN-700(1)CMN-700概述

本章介绍CMN-700&#xff0c;这是用于AMBA5 CHI互连&#xff0c;且可根据需要定制的网格拓扑结构。 1. 关于CMN‐700 CMN‐700是一种可配置扩展的一致性互连网络&#xff0c;旨在满足高端网络和企业计算应用中使用的一致性网络系统的功率、性能和面积(PPA)要求。支持1-256个处…

ES6深潜指南:解锁JavaScript类与继承的高级技巧,让您的代码更加优雅

前言 随着前端技术的迅猛发展&#xff0c;JavaScript已经成为构建现代Web应用不可或缺的编程语言。ES6&#xff08;ECMAScript 2015&#xff09;引入了许多期待已久的特性&#xff0c;其中类&#xff08;Classes&#xff09;和继承机制的引入&#xff0c;极大地增强了JavaScrip…

gc.log中 CMS-concurrent-abortable-preclean

问题 在gc日志中看到 2024-06-26T16:16:07.5040800: 64690272.666: [CMS-concurrent-abortable-preclean-start]CMS: abort preclean due to time 2024-06-26T16:16:12.5530800: 64690277.716: [CMS-concurrent-abortable-preclean: 1.052/5.049 secs] [Times: user1.33 sys0…

Gradle学习-3 Gradle构建的生命周期

Gradle常用文件目录 Gradle 构建的生命周期&#xff0c;有3个阶段: 初始化阶段配置阶段执行阶段 1、初始化阶段 Gradle 支持构建单个工程个多个子工程&#xff0c;初始化阶段主要负责收集所有参与本次构建的子工程&#xff0c;创建一个项目的层次结构&#xff0c;并未每个…

喜报!极限科技新获得一项国家发明专利授权:“搜索数据库的正排索引处理方法、装置、介质和设备”

近日&#xff0c;极限数据&#xff08;北京&#xff09;科技有限公司&#xff08;简称&#xff1a;极限科技&#xff09;新获得一项国家发明专利授权&#xff0c;专利名为 “搜索数据库的正排索引处理方法、装置、介质和设备”&#xff0c;专利号&#xff1a;ZL 2024 1 0479400…

实用软件下载:BetterZip 5最新安装包及详细安装教程

​我们都知道BetterZip是Mac平台上非常受欢迎的文件“解/压缩”工具之一&#xff0c;并且能够生成被Win支持的压缩包。不同领域的应用证明了这是一款功能强大的 Mac 解压缩软件支持 RAR、ZIP等30 种档案格式&#xff0c;可创建小型应用软件。值得一提的是而且能够在不必解压的情…

【教学类-64-05】20240625彩棒鱼骨图(二)AB排列 6.5*1CM 6选2根 30种

背景需求&#xff1a; 【教学类-64-04】20240619彩棒鱼骨图&#xff08;一&#xff09;6.5*1CM 6根棒子720种-CSDN博客文章浏览阅读897次&#xff0c;点赞23次&#xff0c;收藏13次。【教学类-64-04】20240619彩棒鱼骨图&#xff08;一&#xff09;6.5*1CM 6根棒子720种https:…

WordPress强大多功能主题模板The7 v9.16.0

模板介绍 The7可以与WPBakery Page Builder&#xff08;原Visual Composer&#xff09;和Ultimate Addons的完全无缝集成。它也与大多数流行的插件完全兼容&#xff0c;例如WooCommerce&#xff0c;WPML&#xff0c;Yoast SEO&#xff0c;All in One WP Migration&#xff0c;…

视觉分割的定义与性能度量

文章目录 视觉分割的定义语义分割(Semantic Segmentation)实例分割(instance Segmentation)全景分割(Panoptic Segmentation)视频语义分割(Video Semantic Segmentation)视频实例分割(Video instance Segmentation)视频全景分割(Video Panoptic Segmentation)各任务对比 视觉分…

classnames.js 优化类名的工具库

classnames.js 是什么? classnames.js 是一个简单的类名控制工具库,可以方便的通过条件动态控制class类名的显示。 官方代码及示例文档参见:GitHub - JedWatson/classnames: A simple javascript utility for conditionally joining classNames together 为什么要使用 clas…

Linux扩展lvm分区实践 -- 使用其他磁盘的空间

如图&#xff0c;根分区900G&#xff0c;计划将另一块磁盘sdb分出1T来给根分区 步骤 1&#xff1a;创建新的分区 sudo fdisk /dev/sdb输入 n 创建一个新分区 然后选择分区类型&#xff0c;输入p 设置起始扇区&#xff08;默认&#xff09;&#xff0c;然后设置分区大小&…

服务器部署与DDOS攻防

知识点&#xff1a;DHPC与Web服务部署&#xff0c;DHCPig攻防&#xff0c;SYN Flooding测试 DHCP&#xff1a; 能够自动为客户机获取IP等参数 DHCP是动态主机配置协议&#xff08;Dynamic Host Configuration Protocol&#xff09;的缩写&#xff0c;它是一种网络管理协议&am…

633. 平方数之和(中等)

633. 平方数之和 1. 题目描述2.详细题解3.代码实现3.1 Python3.2 Java内存溢出溢出代码正确代码与截图 1. 题目描述 题目中转&#xff1a;633. 平方数之和 2.详细题解 本题是167. 两数之和 II - 输入有序数组&#xff08;中等&#xff09;题目的变型&#xff0c;由两数之和变…

PS系统教程30

图层蒙版组合使用 案例介绍 全选背景图-复制背景图粘贴背景图CtrlI反选背景色填充黑色快速选区工具框柱需要素材画笔涂抹白色 步骤截图 1-3 4-5 图层蒙版与渐变工具结合使用 案例2 注意 使用PS的渐变工具覆盖全部的原因可能包括操作不当或设置错误。 操作不当&#xff1…

docker入门配置

1、创建配置镜像 由于国内docker连接外网速度慢&#xff0c;采用代理 vi /etc/docker/daemon.json添加以下内容 {"registry-mirrors": ["https://9cpn8tt6.mirror.aliyuncs.com","https://dockerproxy.com","https://hub-mirror.c.163.co…

Opencv中RotatedRect和ellipse的角度方向

版本&#xff1a;opencv-4.7.0-windows Opencv中&#xff0c;大多数时候&#xff0c;逆时针旋转是正方向&#xff0c;但在RotatedRect和ellipse中&#xff0c;顺时针旋转是正方向。 //RotatedRect的角度参数是顺时针为正方向 RotatedRect(const Point2f& center, const Si…

鸿蒙开发Ability Kit(程序框架服务):【FA模型切换Stage模型指导】 app和deviceConfig的切换

app和deviceConfig的切换 为了便于开发者维护应用级别的属性配置&#xff0c;Stage模型将config.json中的app和deviceConfig标签提取到了app.json5中进行配置&#xff0c;并对部分标签名称进行了修改&#xff0c;具体差异见下表。 表1 配置文件app标签差异对比 配置项FA模型…

交通大数据分析与挖掘实训【对提供的CSV格式数据使用pandas库分析-Matplotlib库绘图】

背景&#xff1a; 《交通大数据分析与挖掘》实训 指 导 书 编著 二○二四年五月 一、实训目的 1、掌握python开发环境&#xff08;如Anaconda&#xff09;及Numpy等常见第三方库的使用&#xff1b; 2、熟悉Anaconda在线编程平台&#xff0c;学会基本的python程序编写…