如何在 ESP32 上正确读取 POST REQUEST 正文

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

我正在尝试在微控制器 ESP32 上创建服务器和客户端交互。它将由简单的 HTTP 服务器和客户端组成。所以客户端会向服务器发送一个POST请求,服务器会根据收到的数据做一些逻辑处理。 对于更多上下文,这里是服务器端代码:

      if (client.available()) {             // if there's bytes to read from the client,
        char c = client.read();             // read a byte, then
        Serial.write(c);                    // print it out the serial monitor
        header += c;
        if (c == '\n') {                    // if the byte is a newline character
          // if the current line is blank, you got two newline characters in a row.
          // that's the end of the client HTTP request, so send a response:
          if (currentLine.length() == 0) {


            int contentLength = header.indexOf("Content-Length: ");
              if (contentLength != -1) {
                contentLength = header.substring(contentLength + 16).toInt();
                int bodyRead = 0;
                  while (bodyRead < contentLength && client.available()) {
                      char c = client.read();
                      requestBody += c;
                      bodyRead++;
                  }
              }

              // Separate direction and vehicle id
              int sd = requestBody.indexOf('=');
              int vd = requestBody.indexOf('&');

              String direction = requestBody.substring(sd + 1, vd);

              int pos = requestBody.indexOf('=', vd);

              String vehicle = requestBody.substring(pos + 1);
       
              // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
              // and a content-type so the client knows what's coming, then a blank line:
              client.println("HTTP/1.1 200 OK");
              client.println("Content-type:text/html");
              client.println("Connection: close");
              client.println("Got it, " + direction + " for : " + vehicle);
              client.println();
              Serial.println("Request Body : " + requestBody);
              Serial.println("Direction : " + direction);
              Serial.println("Vehicle : " + vehicle);
            // Break out of the while loop
            break;
          } else { // if you got a newline, then clear currentLine
            currentLine = "";
          }
        } else if (c != '\r') {  // if you got anything else but a carriage return character,
          currentLine += c;      // add it to the end of the currentLine
        }
      }

这是客户端代码:

    if(WiFi.status()== WL_CONNECTED){
      WiFiClient client;
      HTTPClient http;
    
      // Your Domain name with URL path or IP address with path
      http.begin(client, serverName);
      
      // Specify content-type header
      http.addHeader("Content-Type", "application/x-www-form-urlencoded");
      // Data to send with HTTP POST
      String httpRequestData = "from=south&id=military";           
      // Send HTTP POST request
      int httpResponseCode = http.POST(httpRequestData);
     
      Serial.print("HTTP Response code: ");
      Serial.println(httpResponseCode);
        
      // Free resources
      http.end();
    }
    else {
      Serial.println("WiFi Disconnected");
    }

现在的问题是服务器无法正确读取POST请求。 在测试客户端之前,我使用 API Tester(移动应用程序)来测试服务器,它按预期工作。所以我的服务器在串行监视器中打印出这些:

POST / HTTP/1.1
user-agent: apitester.org Android/7.5(641)
accept: */*
Content-Type: application/x-www-form-urlencoded
Content-Length: 22
Host: 192.168.4.1
Connection: Keep-Alive
Accept-Encoding: gzip

Request Body : from=south&id=military
Direction : south
Vehicle : military
Client disconnected.

但是当我从客户端发送 POST 请求时,我的服务器不会在串行监视器上返回任何数据

POST / HTTP/1.1
Host: 192.168.4.1
User-Agent: ESP32HTTPClient
Connection: keep-alive
Accept-Encoding: identity;q=1,chunked;q=0.1,*;q=0
Content-Type: application/x-www-form-urlencoded
Content-Length: 23

Request Body : 
Direction : 
Vehicle : 
Client disconnected.

我还没弄清楚为什么会发生这种情况。我猜错误是在客户端?因为服务器在与 API Tester 一起使用时才能工作。但从我阅读的许多教程来看,我的客户端代码应该可以正常工作。

另外因为没有错误代码之类的东西,我不知道应该从哪里解决这个问题。我希望你能帮我解决这个问题。

仅此而已,欢迎任何反馈,谢谢

c++ http arduino esp32
1个回答
0
投票

当您从

Content-Length
中提取
header
值时,您期望
Content-Length
是存储在
header
中的最后一行,但在您的示例中显然不是这种情况。

您需要找到整数值后面的

'\r'
字符(因为您没有将
'\n'
字符添加到
header
),然后仅提取
"Content-Length: "
'\r'
之间的行部分。您当前正在提取从
"Content-Length: "
header
末尾的所有内容。

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