使用 ESP8266WiFi 库发送 HTTP POST 请求

Sending HTTP POST request using ESP8266WiFi library

我有一个 nodejs/expressjs 后端服务,我希望使用端点注册我的设备。我必须向我的服务器发送一个 POST 请求,其中包含一些 json 编码数据。我很难做到这一点。我可以成功发送 GET 请求并从服务器获得响应,但是当我尝试发送 POST 请求时,我没有收到任何响应。这是我的做法:

//Make a post request
void postRequest(const char* url, const char* host, String data){
  if(client.connect(host, PORT)){
    client.print(String("POST ") + url + " HTTP/1.1\r\n" +
                 "Host: " + host + "\r\n" +
                 //"Connection: close\r\n" +
                 "Content-Type: application/json\r\n" +
                 "Content-Length: " + data.length() + "\r\n" +
                 data + "\n");
    //Delay
    delay(10);

    // Read all the lines of the reply from server and print them to Serial
    CONSOLE.println("Response: \n");
    while(client.available()){
        String line = client.readStringUntil('\r');
        CONSOLE.print(line);
    }
  }else{
    CONSOLE.println("Connection to backend failed.");
    return;
  }
}

您的请求几乎正确。 HTTP Message Spec 声明你需要在每个头端都有一个 CR+LF 对,你有,然后为了表示正文开始,你有一个包含 only CR 的空行+LF 对。

你的代码应该看起来像这样加上额外的对

client.print(String("POST ") + url + " HTTP/1.1\r\n" +
                 "Host: " + host + "\r\n" +
                 //"Connection: close\r\n" +
                 "Content-Type: application/json\r\n" +
                 "Content-Length: " + data.length() + "\r\n" +
                 "\r\n" + // This is the extra CR+LF pair to signify the start of a body
                 data + "\n");

此外,我会稍微修改延迟,因为服务器可能不会在 10 毫秒内响应。如果没有,您的代码将永远不会打印响应,并且会丢失。你可以按照这个做一些事情来确保它在放弃响应之前至少等待一定的时间

int waitcount = 0;
while (!client.available() && waitcount++ < MAX_WAIT_COUNT) {
     delay(10);
}

// Read all the lines of the reply from server and print them to Serial
CONSOLE.println("Response: \n");
while(client.available()){
    String line = client.readStringUntil('\r');
    CONSOLE.print(line);
}

此外,如果您使用的是 Arduino ESP8266 环境,他们有一个 编写的 HTTP 客户端库可能会帮助您,因此您不必编写这样的低级 HTTP 代码。您可以找到一些使用它的示例 here