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头部。
可以达到相同的效果。