如何使用boost::beast检测ajax请求



我需要检测请求是通过ajax发送的还是没有使用boost beast http解析器

其他编程语言中的一些http框架提供了此功能。但是如何用boost::beast实现这一点呢?

我知道这取决于客户端发送的数据,而这些数据并不总是可信的。但是,如果客户机通过浏览器发送了所有必需的数据,那么基于客户机数据确定Ajax请求的正确方法是什么呢?

这真的与Beast无关,但从这个页面的想法:https://www.geeksforgeeks.org/how-to-detect-ajax-request-to-normal-request-in-node-js/

  1. 检查请求的头,如果它包含具有XMLHttpRequest值的HTTP_X_REQUESTED_WITH,则它是一个ajax请求。
  2. 当您发出AJAX请求时,它将内容类型application/json添加到请求的标头。所以如果请求包含标题,那么它就是AJAX
  3. 如果referer标头与host标头不同,则它是AJAX请求
  4. 如果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

最新更新