我需要使用 boost beast http 解析器检测请求是否通过 ajax 发送
其他编程语言的 http 的一些框架提供了这种能力。但是如何用 boost::beast 做到这一点呢?
我知道这取决于客户端发送的数据,而这些数据并不总是可信的。但是,如果客户端通过浏览器发送了所有必要的数据,那么根据客户端数据确定 Ajax 请求的正确方法是什么?
这真的与 Beast 无关,但从这个页面获取想法:https://www.geeksforgeeks.org/how-to-detect-ajax-request-to-normal-request-in-node-js /
- 检查请求的标头,如果它包含
具有 XMLHttpRequest 的值,那么它是一个 ajax 请求。HTTP_X_REQUESTED_WITH
- 当您发出 AJAX 请求时,它会将内容类型
添加到请求的标头中。所以如果请求 包含标题然后它是 AJAXapplication/json
- 如果
标头与referer
标头不同那么它是一个 AJAX 请求host
- 如果
标头等于sec-fetch-dest
那么它是一个 AJAX 请求empty
免责声明:我认为这些方法并不可靠,更不用说安全了,但下面的演示应该为您提供一些工具,将您自己的需求转化为野兽代码。
#include <boost/beast.hpp>
#include <iostream>
namespace beast = boost::beast;
namespace http = beast::http;
namespace net = boost::asio;
using net::ip::tcp;
using Request = http::request<http::string_body>;
boost::optional<beast::string_view> header(Request const& req, beast::string_view name) {
auto it = req.find(name);
if (it != req.end())
return it->value();
return {};
}
int main() {
net::io_context ioc;
tcp::acceptor acc(ioc, {{}, 8989});
while (true) {
Request req;
auto sock = acc.accept();
beast::flat_buffer buf;
read(sock, buf, req);
bool is_ajax = req.count("HTTP_X_REQUESTED_WITH") // 1.
|| header(req, "referer") != header(req, "host") // 3.
|| header(req, "sec-fetch-dest") == beast::string_view("empty"); // 4.
std::cout << (is_ajax ? "AJAX " : "Regular ") //
<< req.method_string() << " request " //
<< " for " << req.target() //
<< std::endl;
}
}
对于一些测试:
g++ -std=c++20 -O2 -Wall -pedantic -pthread main.cpp
./a.out&
sleep 1; curl -s http://127.0.0.1:8989/demo1 -d @main.cpp
sleep 1; curl -sH 'referer: 127.0.0.1:8989' "http://127.0.0.1:8989/demo2?the=works"
打印
AJAX POST request for /demo1
Regular GET request for /demo2?the=works