我需要执行 get 和 post 请求,get 请求工作没有问题,但每次我使用前端(react/axios)发布请求时,都会出现以下错误:跨源请求被阻止:同源策略不允许读取远程资源位于 http://localhost:8000/ethernetdata。 (原因:CORS 标头“Access-Control-Allow-Credentials”中预期为“true”)。
XHR帖子 http://localhost:8000/ethernetdata
跨源请求被阻止:同源策略不允许读取 http://localhost:8000/ethernetdata 处的远程资源。 (原因:CORS请求未成功)。状态码:(空)。
但是当我使用邮递员发布或获取请求时,它可以正常工作 这是我的 C++ 服务器代码:
#include <crow.h>
#include <iostream>
#include <sqlite3.h>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
static int callback(void *data, int argc, char **argv, char **azColName){
json *result = reinterpret_cast<json*>(data);
json row;
for(int i=0; i<argc; i++){
row[azColName[i]] = argv[i] ? argv[i] : "";
}
result->push_back(row);
return 0;
}
int main() {
crow::SimpleApp app;
sqlite3 *db;
int rc = sqlite3_open_v2("/home/khairy/work/eventsenderwebserver/Backend/db/data.db", &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, nullptr);
if (rc != SQLITE_OK) {
std::cerr << "Cannot open database: " << sqlite3_errmsg(db) << std::endl;
sqlite3_close(db);
return 1;
}
const char* create_table_sql =
"CREATE TABLE IF NOT EXISTS ethernetdata ("
"id INTEGER PRIMARY KEY,"
"ip TEXT NOT NULL,"
"netmask TEXT NOT NULL,"
"router TEXT NOT NULL,"
"dns1 TEXT NOT NULL,"
"dns2 TEXT NOT NULL,"
"enabled TEXT NOT NULL"
");";
char* err_msg = nullptr;
rc = sqlite3_exec(db, create_table_sql, nullptr, nullptr, &err_msg);
if (rc != SQLITE_OK) {
std::cerr << "SQL error: " << err_msg << std::endl;
sqlite3_free(err_msg);
sqlite3_close(db);
return 1;
}
CROW_ROUTE(app, "/")
.methods("GET"_method,"POST"_method)
([]() {
crow::response response{"Hello,world !"};
response.set_header("Access-Control-Allow-Origin", "*");
response.set_header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
response.set_header("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With");
response.set_header("Access-Control-Allow-Credentials", "true");
return response;
});
CROW_ROUTE(app, "/ethernetdata")
.methods("GET"_method, "POST"_method)
([&db, &rc](const crow::request& req){
json result;
if (req.method == "GET"_method) {
const char* sql = "SELECT * FROM ethernetdata;";
char* err_msg = nullptr;
rc = sqlite3_exec(db, sql, callback, &result, &err_msg);
if (rc != SQLITE_OK) {
std::cerr << "SQL error: " << err_msg << std::endl;
sqlite3_free(err_msg);
}
crow::response response{result.dump()};
response.set_header("Access-Control-Allow-Origin", "*");
return response;
} else if (req.method == "POST"_method) {
// Parse the JSON data from the POST request
json post_data = json::parse(req.body);
// Modify the data in the database based on the POST request
const char* update_sql = "UPDATE ethernetdata SET ip = ?, netmask = ?, router = ?, dns1 = ?, dns2 = ?, enabled = ? WHERE id = 1;";
sqlite3_stmt* stmt;
rc = sqlite3_prepare_v2(db, update_sql, -1, &stmt, nullptr);
if (rc != SQLITE_OK) {
std::cerr << "Cannot prepare statement: " << sqlite3_errmsg(db) << std::endl;
sqlite3_finalize(stmt);
return crow::response{500};
}
sqlite3_bind_text(stmt, 1, post_data["ip"].get<std::string>().c_str(), -1, SQLITE_TRANSIENT);
sqlite3_bind_text(stmt, 2, post_data["netmask"].get<std::string>().c_str(), -1, SQLITE_TRANSIENT);
sqlite3_bind_text(stmt, 3, post_data["router"].get<std::string>().c_str(), -1, SQLITE_TRANSIENT);
sqlite3_bind_text(stmt, 4, post_data["dns1"].get<std::string>().c_str(), -1, SQLITE_TRANSIENT);
sqlite3_bind_text(stmt, 5, post_data["dns2"].get<std::string>().c_str(), -1, SQLITE_TRANSIENT);
sqlite3_bind_text(stmt, 6, post_data["enabled"].get<std::string>().c_str(), -1, SQLITE_TRANSIENT);
rc = sqlite3_step(stmt);
if (rc != SQLITE_DONE) {
std::cerr << "Cannot execute statement: " << sqlite3_errmsg(db) << std::endl;
sqlite3_finalize(stmt);
return crow::response{500};
}
// Populate the result object with the updated data
const char* select_sql = "SELECT * FROM ethernetdata WHERE id = 1;";
char* err_msg = nullptr;
rc = sqlite3_exec(db, select_sql, callback, &result, &err_msg);
if (rc != SQLITE_OK) {
std::cerr << "SQL error: " << err_msg << std::endl;
sqlite3_free(err_msg);
}
crow::response response{result.dump()};
response.set_header("Access-Control-Allow-Origin", "*");
response.set_header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
response.set_header("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With");
response.set_header("Access-Control-Allow-Credentials", "true");
return response;
}
});
app.port(8000).multithreaded().run();
sqlite3_close(db);
return 0;
}
我尝试运行 http 服务器作为我的后端,以使用 C++ 执行 CRUD 请求(库:Crow)
请参阅下面的链接示例,了解如何为您的路线启用 CORS: (来自 Crow github 存储库)
https://github.com/CrowCpp/Crow/blob/master/examples/middlewares/example_cors.cpp
#include "crow.h"
#include "crow/middlewares/cors.h"
int main()
{
// Enable CORS
crow::App<crow::CORSHandler> app;
// Customize CORS
auto& cors = app.get_middleware<crow::CORSHandler>();
// clang-format off
cors
.global()
.headers("X-Custom-Header", "Upgrade-Insecure-Requests")
.methods("POST"_method, "GET"_method)
.prefix("/cors")
.origin("example.com")
.prefix("/nocors")
.ignore();
// clang-format on
CROW_ROUTE(app, "/")
([]() {
return "Check Access-Control-Allow-Methods header";
});
CROW_ROUTE(app, "/cors")
([]() {
return "Check Access-Control-Allow-Origin header";
});
app.port(18080).run();
return 0;
}
对我有用
fetch(url, {
method: 'POST',
mode: 'no-cors',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
week: '1'
})
})
.then(response => {
// Note: with no-cors mode, you cannot access the response body or headers
console.log('Request sent');
})
.catch(error => {
console.error('Error:', error);
});