2

I have a nodejs/expressjs backend service and I wish to register my devices using an endpoint. I have to send a POST request to my server with some json encoded data. I have trouble doing this. I can successfully send a GET request and I get response from the server, however when I try to send a POST request I get no response. Here's how I do it:

//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;
  }
}

1 Answer 1

7

Your request is almost correct. The HTTP Message Spec states you need a CR+LF pair at every header end, which you have, and then to signify the body start, you have an empty line containing only a CR+LF pair.

Your code should look something like this with the extra pair

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");

Also, I would modify the delay slightly, as a server may not respond in 10ms. If it does not, your code will never print a response, and it will be lost. You could do something along the lines of this to ensure it waits at least a certain amount of time before giving up on a response

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);
}

Additionally, if you're using the Arduino ESP8266 environment, they have an HTTP Client library written which may help you out, so you don't have to write low level HTTP code such as this. You can find some examples of using it here

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.