0x00 概述
我们使用Poco库的 Poco::Net::HTMLForm 类可以轻松实现表单数据的提交。
0x01 ApiPost提交表单数据

0x02 HttpClient类
#ifndef HTTPCLIENT_H
#define HTTPCLIENT_H
#include <string>
#include <map>
#include <Poco/URI.h>
#include <Poco/Net/HTTPClientSession.h>
#include <Poco/Net/HTTPRequest.h>
#include <Poco/Net/HTTPResponse.h>
#include <Poco/Net/HTTPCredentials.h>
#include <Poco/Net/HTMLForm.h>
#include <Poco/StreamCopier.h>
#include <Poco/NullStream.h>
#include <Poco/Exception.h>
class HttpClient
{
public:
    HttpClient(const std::string &host, const std::string &port = "80");
    std::string Get(const std::string &path,
                    const std::map<std::string, std::string> &header = std::map<std::string, std::string>());
    // 在Query中添加表单数据
    std::string Post(const std::string &path,
                     const std::map<std::string, std::string> &query = std::map<std::string, std::string>(),
                     const std::map<std::string, std::string> &header = std::map<std::string, std::string>());
    // 在Body中使用JSON或XML数据
    std::string Post(const std::string &path,
                     const std::string &body,
                     const std::map<std::string, std::string> &header = std::map<std::string, std::string>());
    bool DoRequest(Poco::Net::HTTPClientSession &session,
                   Poco::Net::HTTPRequest &request,
                   Poco::Net::HTTPResponse &response,
                   std::string &responseMsg);
    bool DoRequest(Poco::Net::HTTPClientSession &session,
                   Poco::Net::HTTPRequest &request,
                   Poco::Net::HTTPResponse &response,
                   Poco::Net::HTMLForm &Query,
                   std::string &responseMsg);
    bool DoRequest(Poco::Net::HTTPClientSession &session,
                   Poco::Net::HTTPRequest &request,
                   Poco::Net::HTTPResponse &response,
                   const std::string &Body,
                   std::string &responseMsg);
private:
    std::string m_host;
    std::string m_port;
};
#endif // HTTPCLIENT_H
 
#include "httpclient.h"
#include <sstream>
HttpClient::HttpClient(const std::string &host, const std::string &port)
    : m_host(host), m_port(port)
{
}
std::string HttpClient::Get(const std::string &path,
                            const std::map<std::string, std::string> &header)
{
    try
    {
        Poco::Net::HTTPClientSession session(m_host, std::stoi(m_port));
        Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, path, Poco::Net::HTTPMessage::HTTP_1_1);
        // 设置请求头
        request.set("User-Agent", "PocoRuntime-PocoRuntime/1.1.0");
        for (auto item : header)
        {
            request.set(item.first, item.second);
        }
        Poco::Net::HTTPResponse response;
        std::string retMsg;
        if (DoRequest(session, request, response, retMsg))
        {
            printf("%s\n", retMsg.c_str());
        }
        return retMsg;
    }
    catch (const Poco::Exception &ex)
    {
        printf("%s\n", ex.displayText().c_str());
    }
    return "";
}
std::string HttpClient::Post(const std::string &path,
                             const std::map<std::string, std::string> &query,
                             const std::map<std::string, std::string> &header)
{
    try
    {
        Poco::Net::HTTPClientSession session(m_host, std::stoi(m_port));
        Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_POST, path, Poco::Net::HTTPMessage::HTTP_1_1);
        // 设置请求头
        request.set("User-Agent", "PocoRuntime-PocoRuntime/1.1.0");
        for (auto item : header)
        {
            request.set(item.first, item.second);
        }
        // 设置请求参数
        Poco::Net::HTMLForm formQuery;
        for (auto item : query)
        {
            formQuery.add(item.first, item.second);
        }
        formQuery.prepareSubmit(request);
        Poco::Net::HTTPResponse response;
        std::string retMsg;
        if (DoRequest(session, request, response, formQuery, retMsg))
        {
            printf("%s\n", retMsg.c_str());
        }
        return retMsg;
    }
    catch (const Poco::Exception &ex)
    {
        printf("[%s:%d] %s\n", __FILE__, __LINE__, ex.displayText().c_str());
    }
    return "";
}
std::string HttpClient::Post(const std::string &path,
                             const std::string &body,
                             const std::map<std::string, std::string> &header)
{
    try
    {
        Poco::Net::HTTPClientSession session(m_host, std::stoi(m_port));
        Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_POST, path, Poco::Net::HTTPMessage::HTTP_1_1);
        // 设置请求头
        request.set("User-Agent", "PocoRuntime-PocoRuntime/1.1.0");
        for (auto item : header)
        {
            request.set(item.first, item.second);
        }
        // XML类型的请求体
        // request.setContentType("application/xml");
        // request.setContentLength(body.length());
        Poco::Net::HTTPResponse response;
        std::string retMsg;
        if (DoRequest(session, request, response, body, retMsg))
        {
            printf("%s\n", retMsg.c_str());
        }
        return retMsg;
    }
    catch (const Poco::Exception &ex)
    {
        printf("[%s:%d] %s\n", __FILE__, __LINE__, ex.displayText().c_str());
    }
    return "";
}
bool HttpClient::DoRequest(Poco::Net::HTTPClientSession &session,
                           Poco::Net::HTTPRequest &request,
                           Poco::Net::HTTPResponse &response,
                           std::string &repMsg)
{
    session.sendRequest(request);                         // 发送请求
    std::istream &is = session.receiveResponse(response); // 接收响应
    std::ostringstream oss;
    printf("[%s:%d] %d %s\n", __FILE__, __LINE__, response.getStatus(), response.getReason().c_str());
    if (response.getStatus() != Poco::Net::HTTPResponse::HTTP_UNAUTHORIZED)
    {
        // Poco::StreamCopier::copyStream(rs, std::cout);
        Poco::StreamCopier::copyStream(is, oss);
        if (!oss.str().empty())
        {
            // printf("[%s:%d] %s\n", __FILE__, __LINE__, oss.str().c_str());
            repMsg = oss.str();
        }
        return true;
    }
    else
    {
        printf("[%s:%d] -----HTTPResponse error-----\n", __FILE__, __LINE__);
        Poco::NullOutputStream null;
        Poco::StreamCopier::copyStream(is, null);
        return false;
    }
}
bool HttpClient::DoRequest(Poco::Net::HTTPClientSession &session,
                           Poco::Net::HTTPRequest &request,
                           Poco::Net::HTTPResponse &response,
                           Poco::Net::HTMLForm &Query,
                           std::string &responseMsg)
{
    std::ostream &os = session.sendRequest(request); // 发送请求
    // 添加请求参数
    Query.write(os);
    os.flush();
    std::istream &is = session.receiveResponse(response); // 接收响应
    std::ostringstream oss;
    printf("[%s:%d] %d %s\n", __FILE__, __LINE__, response.getStatus(), response.getReason().c_str());
    if (response.getStatus() != Poco::Net::HTTPResponse::HTTP_UNAUTHORIZED)
    {
        // Poco::StreamCopier::copyStream(rs, std::cout);
        Poco::StreamCopier::copyStream(is, oss);
        if (!oss.str().empty())
        {
            // printf("[%s:%d] %s\n", __FILE__, __LINE__, oss.str().c_str());
            responseMsg = oss.str();
        }
        return true;
    }
    else
    {
        printf("[%s:%d] -----HTTPResponse error-----\n", __FILE__, __LINE__);
        Poco::NullOutputStream null;
        Poco::StreamCopier::copyStream(is, null);
        return false;
    }
}
bool HttpClient::DoRequest(Poco::Net::HTTPClientSession &session,
                           Poco::Net::HTTPRequest &request,
                           Poco::Net::HTTPResponse &response,
                           const std::string &Body,
                           std::string &responseMsg)
{
    std::ostream &os = session.sendRequest(request); // 发送请求
    // 添加请求体
    os << Body;
    os.flush();
    std::istream &is = session.receiveResponse(response); // 接收响应
    std::ostringstream oss;
    printf("[%s:%d] %d %s\n", __FILE__, __LINE__, response.getStatus(), response.getReason().c_str());
    if (response.getStatus() != Poco::Net::HTTPResponse::HTTP_UNAUTHORIZED)
    {
        // Poco::StreamCopier::copyStream(rs, std::cout);
        Poco::StreamCopier::copyStream(is, oss);
        if (!oss.str().empty())
        {
            // printf("[%s:%d] %s\n", __FILE__, __LINE__, oss.str().c_str());
            responseMsg = oss.str();
        }
        return true;
    }
    else
    {
        printf("[%s:%d] -----HTTPResponse error-----\n", __FILE__, __LINE__);
        Poco::NullOutputStream null;
        Poco::StreamCopier::copyStream(is, null);
        return false;
    }
}
 
0x03 使用方法
#include <iostream>
#include <memory>
#include "httpclient.h"
using namespace std;
int main()
{
    std::unique_ptr<HttpClient> httpCli(new HttpClient("localhost", "18080"));
    std::map<std::string, std::string> header{{"content-type", "application/x-www-form-urlencoded"}};
    // localhost:18080?name=admin&password=admin&gender=male&subscribe=on
    std::map<std::string, std::string> query{{"name", "admin"},
                                             {"password", "admin"},
                                             {"gender", "male"},
                                             {"subscribe", "on"}};
    // 提交表单数据
    httpCli->Post("/", query, header);
    cout << "==Over==" << endl;
    return 0;
}
                


















