Problems with ESP32 Web Server handling POST requests
Posted: Tue Jul 09, 2024 1:38 pm
I'm developing a very basic web server as part of an IoT project on an ESP32-S3.
I have a web page with an input box and up / down buttons. My aim is to get the value in the input box to change each time the button is pressed and then POST the new value to the web server for processing.
The web page appears to work OK, but there are two problems.
Here is an example of the console output in the ESP32 IDE (with two extra characters "h☺" on the end of the buffer)
And after the button is pressed several times
So it looks like I'm trying to open a new connection each time the message is posted - so I'm guessing I need to find a way to keep the connection open while the web page is open.
In case it's relevant, here's the javascript I use to post the messages to the ESP32 server
Thanks for your support
I have a web page with an input box and up / down buttons. My aim is to get the value in the input box to change each time the button is pressed and then POST the new value to the web server for processing.
The web page appears to work OK, but there are two problems.
- When I parse the message content there are some extra characters that were not sent by the web page
- If I press the button more than 5 or 6 times the server stops handling the POST messages until the page is refreshed manually
Code: Select all
// WiFi web pages
#include "handler.h"
//#include "timer.h"
#include "helper.h"
#include "esp_wifi.h"
#include <sys/param.h>
#include "nvs.h"
#include "globals.h"
#include "functions.h"
static const char *TAG = "Control Handler";
esp_err_t control_handler(httpd_req_t *req)
{
ESP_LOGI(TAG,"Loading Control Page");
httpd_req_to_sockfd(req);
static esp_err_t out;
if (req->method == HTTP_POST) //Data has been entered and needs to be handled
{
int ret, remaining = req->content_len;
char buf[req->content_len];
while (remaining > 0)
{
/* Read the data for the request */
if ((ret = httpd_req_recv(req, buf, MIN(remaining, sizeof(buf)))) <= 0)
{
if (ret == HTTPD_SOCK_ERR_TIMEOUT)
{
continue;
}
ESP_LOGE(TAG, "Timeout occured");
return ESP_FAIL;
}
remaining -= ret;
}
//Now extract the parameters from the buffer
size_t contentLength = 64;
char PAN_Angle[contentLength], TILT_Angle[contentLength], Control_Mode[contentLength];
ESP_LOGE(TAG,"Buffer: %s",buf);
readUrlParameterIntoBuffer(buf, "pan", PAN_Angle, contentLength);
readUrlParameterIntoBuffer(buf, "tilt", TILT_Angle, contentLength);
readUrlParameterIntoBuffer(buf, "mode", Control_Mode, contentLength);
ESP_LOGI(TAG, "Processed form %s/%s/%s", Control_Mode, PAN_Angle, TILT_Angle);
// Send an HTTP response
httpd_resp_set_status(req, "200 OK");
out = ESP_OK;
return out;
}
}
Code: Select all
E (1744596) Control Handler: Buffer: pan=0&tilt=22&mode=Automatich☺
I (1744596) urihelper: Found 'pan' parameter => 0
I (1744596) urihelper: Found 'tilt' parameter => 22
I (1744606) urihelper: Found 'mode' parameter => Automatich☺
I (1790846) Control Handler: Processed form Automatich☺/0/24
Code: Select all
E (1794996) httpd: httpd_accept_conn: error in accept (23)
W (1794996) httpd: httpd_server: error accepting new connection
In case it's relevant, here's the javascript I use to post the messages to the ESP32 server
Code: Select all
// Function to post value to the server
function postValueToServer(value) {
const message = 'pan='+ panInput.value + '&tilt=' + tiltInput.value + '&mode=' + document.querySelector('input[name="mode"]:checked').value;
console.log(message);
// Implement your server-side logic here
console.log(`Posting value ${value} to the server...`);
// You can use AJAX or fetch to send the value to your server endpoint
const xhr = new XMLHttpRequest();
xhr.open('POST', '/control', true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
console.log('Value posted successfully:', message);
}
};
xhr.send(message);
}
Thanks for your support