我需要检测请求是通过ajax发送的还是没有使用boost beast http解析器
其他编程语言中的一些http框架提供了此功能。但是如何用boost::beast实现这一点呢?
我知道这取决于客户端发送的数据,而这些数据并不总是可信的。但是,如果客户机通过浏览器发送了所有必需的数据,那么基于客户机数据确定Ajax请求的正确方法是什么呢?
这真的与Beast无关,但从这个页面的想法:https://www.geeksforgeeks.org/how-to-detect-ajax-request-to-normal-request-in-node-js/
- 检查请求的头,如果它包含具有XMLHttpRequest值的
HTTP_X_REQUESTED_WITH
,则它是一个ajax请求。- 当您发出AJAX请求时,它将内容类型
application/json
添加到请求的标头。所以如果请求包含标题,那么它就是AJAX- 如果
referer
标头与host
标头不同,则它是AJAX请求- 如果
sec-fetch-dest
头等于empty
,那么这是一个AJAX请求
免责声明:我不认为这些方法是可靠的,更不用说安全了,但下面的演示应该给你一些工具,把你自己的需求转换成野兽代码。
Live On Coliru
#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