使用 ESP32 发送 HTTP POST 请求

问题描述 投票:0回答:1

为了清晰起见进行编辑
我请求帮助的主要内容是我的

client::SendPostRequest
函数中的 HTTP 参数。我认为由于各种原因,这个问题很相似。我对HTTP不熟悉,想知道熟悉的人是否一眼就能看出它是否有错。我按请求添加更多代码,但主要是寻找确认以下代码行使用参数格式化 HTTP POST 请求的正确或不正确方法。我感谢任何帮助或想法!如果有人提供更多信息,请告诉我。

httpClient.addHeader("Content-Type", "application/x-www-form-urlencoded");
int httpCode = httpClient.POST("/?message=" + message);

我正在编写一个应用程序,其中 ESP32 可以相互通信并充当客户端和服务器。我正在使用 HTTP 来执行此操作。 库用于客户端, 库用于服务器。我相信我在服务器上的路由设置正确,因为我是根据 GitHub 页面中的简单服务器示例对其进行建模的。

https://github.com/me-no-dev/ESPAsyncWebServer/blob/master/examples/simple_server/simple_server.ino

但我相信我没有使用参数(使用客户端代码)正确形成 POST 消息。我是 HTTP 通信新手,所以我认为有些问题。这是我发出 POST 请求的函数。

/*
Function: Try sending some info to a server
(url): The server's url
Returns: HTTP code representing sucess or an error
*/
String client::SendPostRequest(String url, String message)
{
    Serial.println("Client Sending Post");
    HTTPClient httpClient;

    // Connect to server and try to send the message
    httpClient.begin(url);
    //int httpCode = httpClient.POST("/?message" + message);
    httpClient.addHeader("Content-Type", "text/plain");
    int httpCode = httpClient.POST("/?message=" + message);

    String resultInfo;
    if (httpCode > 0)
    {
        // Serial.println(httpClient.getString());
        resultInfo = "Success, HTTP Response Code: " + (String)httpCode;
    }
    else
    {
        resultInfo = "Error, HTTP Response Code: " + (String)httpCode;
    }

    httpClient.end();
    return resultInfo;
}

我在线查看了几个网站,尝试了另一个堆栈溢出问题中的一些内容,并尝试使用聊天 GPT 来解决此问题。我已将主草图上传到两个 ESP32(ESP32 #1 和 ESP32 #2)。 ESP32 #1 发出 POST 请求,将“测试测试 1 2 3”发送到 ESP32 #2。 ESP32 #2 向 ESP32 #1 发出 GET 请求。 GET 请求工作正常。对于 POST 请求,ESP32 #1 发送 post 请求,并看到已发送成功代码 200。然后 ESP32 运行代码,在其服务器上设置到该 URL 的 POST 路由。然而 ESP32 从不打印该消息。我认为它永远不会打印它,因为我的 SendPostRequest 代码设置 POST 参数不正确。设置 POST 路由的服务器代码如下。我的 ESP32 #2 服务器打印“服务器运行发布请求”,但 if (request->hasParam("message", true)) 永远不会计算为 true。如果它工作正常,我希望看到“服务器收到帖子消息 = 测试测试 1 2 3”。预先感谢您的任何帮助或建议!

// Post request
webServer->on("/postTest", HTTP_POST, [](AsyncWebServerRequest *request)
{
    Serial.println("Server running post request");
    String message;
    if (request->hasParam("message", true)) 
    {
        message = request->getParam("message", true)->value();
        Serial.println("Server got post message = " + (String)message);
    } 
    else 
    {
        message = "No message sent";
    }

    request->send(200, "text/plain", "Hello, POST: " + message);
});

ESP32 #1 串行监视器输出:

Server running get request
ESP #1: Loop=4 | Success, HTTP Response Code: 200
Client Sending Post
Server running get request
ESP #1: Loop=5 | Success, HTTP Response Code: 200
Server running get request
Client Sending Post
ESP #1: Loop=6 | Success, HTTP Response Code: 200
Server running get request
Client Sending Post
Server running get request
ESP #1: Loop=7 | Success, HTTP Response Code: 200

ESP32 #2 串行监视器输出:

Client Sending GET
ESP #2: Loop=339 | Hello, world from ESP32
Server running post request **<-- I want to see "Server got post message = Testing Testing 1 2 3 after this line**
Client Sending GET
ESP #2: Loop=340 | Hello, world from ESP32
Server running post request
Client Sending GET
ESP #2: Loop=341 | Hello, world from ESP32
Server running post request
Client Sending GET
ESP #2: Loop=342 | Hello, world from ESP32
Client Sending GET
Server running post request
ESP #2: Loop=343 | Hello, world from ESP32

编辑根据要求,我添加了每个 ESP32 运行的完整代码。 这是主要的 .ino 草图。

#include "client.h"
#include "device.h"
#include "menu.h"
#include "server.h"
#include "wifi.h"  

unsigned long testCount;
bool isServer1 = false;

client oClient;
device oDevice;
menu oMenu;
server oServer; 
wifi oWifi;

void setup()
{
    testCount = 0;
    Serial.begin(115200);

    oMenu.InitalizeScreen();

    int port;
    String espName;
    if(isServer1)
    {
        port = 80;
        espName = "ESP32 #1";
        Serial.println(espName);
        oServer.SetPort(port);
    }
    else
    {
        espName = "ESP32 #2";
        port = 10555;
        Serial.println(espName);
        oServer.SetPort(port);
    }

    // Try connecting to WiFi and start acting as a server for this room
    oWifi.Connect();
    oMenu.Connecting();
    oServer.StartServer();

    // Display networking information on the screen
    oMenu.NetworkingInfo(espName, oWifi.GetIpAddress(), (String)port);
}

void loop()
{
    if(oWifi.IsConnected())
    {
        String message;
        if(isServer1)
        {
            //message = oClient.SendGetRequest("http://192.168.43.117:10555/"); // connect to 2 from 1
            // Send some data to server 2 from server 1
            message = oClient.SendPostRequest("http://192.168.43.117:10555/postTest", "Testing Testing 1 2 3");
            //message = oClient.SendPostRequest("http://192.168.43.100:80/postTest", "Testing Testing 1 2 3");
        }
        else
        {
            message = oClient.SendGetRequest("http://192.168.43.100:80/"); // connect to 1 from 2
        }
        
        if(isServer1)
        {
            Serial.print("ESP #1: Loop=" + (String)testCount + " | ");
        }
        else
        {
            Serial.print("ESP #2: Loop=" + (String)testCount + " | ");
        }
        Serial.println(message);
    }

    delay(2000);
    testCount = testCount + 1;
}

这是我的服务器类的完整 .ino 文件。

#include "server.h"

/*
Function: Create the server listening on port 80 by default
*/
server::server()
{
    server::port = 80;
}

/*
Function: Create the server listening on a specified port
(port): port number to listen on
*/
server::server(unsigned int port)
{
    server::port = port;
}

/*
Function: Free memory for stuff allocated on heap
*/
server::~server()
{
    delete server::webServer;
}

/*
Function: Create response for when the server is not found
(request): HTTP request to this server
*/
void server::NotFound(AsyncWebServerRequest *request) 
{
    request->send(404, "text/plain", "Not found");
}

/*
Function: Set the port to listen to
(port): port number to listen to
*/
void server::SetPort(unsigned int port)
{
    server::port = port;
}

/*
Function: create responses for different HTTP requests
(webServer): This objects web server. Things sending HTTP request to it get these responses
*/
void server::SetupResponses(AsyncWebServer* webServer)
{
    // Get request
    webServer->on("/", HTTP_GET, [](AsyncWebServerRequest *request)
    {
        Serial.println("Server running get request");
        request->send(200, "text/plain", "Hello, world from ESP32");
    });

    // Post request
    webServer->on("/postTest", HTTP_POST, [](AsyncWebServerRequest *request)
    {
        Serial.println("Server running post request");
        String message;
        if (request->hasParam("message", true)) 
        {
            message = request->getParam("message", true)->value();
            Serial.println("Server got post message = " + (String)message);
        } 
        else 
        {
            message = "No message sent";
        }

        request->send(200, "text/plain", "Hello, POST: " + message);
    });

    webServer->onNotFound(NotFound);
}

/*
Function: Start the server
*/
void server::StartServer()
{
    server::webServer = new AsyncWebServer(server::port);
    server::SetupResponses(webServer);
    webServer->begin();
}

这是我的客户端类的完整 .ino 文件。

#include "client.h"

/*
Function: Try to get information from a server
Returns: Returns the payload when successful. Returns an error message when it's not sucessful.
*/
String client::SendGetRequest(String url)
{
    Serial.println("Client Sending GET");
    HTTPClient httpClient;
    String getMessage = "Error on HTTP GET request";

    // Send get request to that URL
    httpClient.begin(url);
    int httpCode = httpClient.GET();  

    if (httpCode > 0) 
    { 
        getMessage = httpClient.getString();
    } 
    else
    {
        getMessage = getMessage + " | Error Code: " + (String)httpCode;
    }

    httpClient.end(); 

    return getMessage;
}


/*
Function: Try sending some info to a server
(url): The server's url
Returns: HTTP code representing sucess or an error
*/
String client::SendPostRequest(String url, String message)
{
    Serial.println("Client Sending Post");
    HTTPClient httpClient;

    // Connect to server and try to send the message
    httpClient.begin(url);
    //int httpCode = httpClient.POST("/?message" + message);
    // httpClient.addHeader("Content-Type", "text/plain");
    httpClient.addHeader("Content-Type", "application/x-www-form-urlencoded");
    int httpCode = httpClient.POST("/?message=" + message);

    String resultInfo;
    if (httpCode > 0)
    {
        // Serial.println(httpClient.getString());
        resultInfo = "Success, HTTP Response Code: " + (String)httpCode;
    }
    else
    {
        resultInfo = "Error, HTTP Response Code: " + (String)httpCode;
    }

    httpClient.end();
    return resultInfo;
}
http post esp32 arduino-c++
1个回答
0
投票

在 esp32 Arduino HTTPClient 库中,

httpClient.POST
的参数是请求的正文。 HTTP POST 请求不应包含 URL 参数。

使用内容类型“application/x-www-form-urlencoded”,esp32 Arduino WebServer 会将 POST 请求的正文解析为 URL 参数,因此您将使用

request->getParam
读取参数的值。

要在 POST 请求正文中包含有效的 URL 参数字符串,请删除“/?”来自

httpClient.POST("/?message=" + message);

© www.soinside.com 2019 - 2024. All rights reserved.