ESPAsyncWebServer POST method for any example with GUI working?

I just want to have any program work where there are a few buttons, a user selects one, and a command is sent to the ESP32. The GUI should stay the same (not change into a submenu).

.ino

#include <WiFi.h>
#include <ESPAsyncWebServer.h>
#include <SPIFFS.h>
#include <painlessMesh.h>

const char* ssid = "Wireless Controller";
const char* password = "12345678";

// User stub
void sendMessage() ; // Prototype so PlatformIO doesn't complain

Task taskSendMessage( TASK_SECOND * 1 , TASK_FOREVER, &sendMessage );

void sendMessage() {
  taskSendMessage.setInterval( random( TASK_SECOND * 1, TASK_SECOND * 5 ));
}

AsyncWebServer server(80);

IPAddress IP(192, 168, 1, 1);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);



void notFound(AsyncWebServerRequest *request) {
    request->send(404, "text/plain", "Not found");
}



void setup()
{
  Serial.begin(115200);

  // Initialize SPIFFS
  if (!SPIFFS.begin(true))
  {
    Serial.println("An Error has occurred while mounting SPIFFS");
    return;
  }


  WiFi.softAP(ssid, password);
  delay(500);
  WiFi.softAPConfig(IP, gateway, subnet);
  IPAddress IP = WiFi.softAPIP();
  Serial.print("AP IP address: ");
  Serial.println(IP);


  server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) 
  {
    request->send(SPIFFS, "/index.html", String(), false);  
  });


  server.on("/post", HTTP_POST, [](AsyncWebServerRequest * request) 
  {
    int paramsNr = request->params(); // number of params (e.g., 1)
    Serial.println(paramsNr);
    Serial.println();
    
    AsyncWebParameter * j = request->getParam(0); // 1st parameter
    Serial.print("Size: ");
    Serial.print(j->value());                     // value ^
    Serial.println();

    request->send(200);
  });
     
  
  server.onNotFound(notFound);

  server.begin();
}

void loop() {}

HTML

<!DOCTYPE html>
<html>
<body>

  <h1>Menu 1</h1>

<form action="/post"  method="post" target="hidden-form"> 

  <p><button class="submit" name="circle" value="6">Circle</button></p>
  <p><button class="submit" name="square" value="4">Square</button></p>

</form>

</body>
</html>

The tutorials and examples I've seen (maybe I missed one), do not have a GUI (web-page). I'm not sure how to get the POST method to work. A similar program half-works with the GET method. I think to successfully accomplish the simple minimal function, GET and POST are needed.

Please try this on your own or I do not want your help. I've gotten a bunch of advice on what to do that didn't help. It's only two files and maybe three libraries. Maybe there needs to be an href involved?

File structure

sketch (folder)

  • sketch.ino
  • data (folder)
    • index.html

I'm not sure what this means ???


Assuming you have a WiFi network which you can join, Here is a very simple code (update with your SSID and PWD) that sets up a web page (the Serial monitor will show which address to use) with two buttons B1 and B2

image

Clicking on one of the button triggers a POST request to be sent to the ESP32 where the action() function is run (in which I just dump the POST information).

The callback does return the same page back to the web browser, and depending on your environment (since it's the same URL) you might get a display refresh or not. if the page is very small like this one, you can't really see it.

if you really want no update to the web page (but even possibly returning some data), then you need to go to AJAX or WebSockets and the likes.

#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
AsyncWebServer server(80);

const char* ssid = "xxx";
const char* password = "xxx";

const char index_html[] PROGMEM = "<form action='action' method='post'><input type='submit' name='B1' value='B1'><input type='submit' name='B2' value='B2'></form>";

void action(AsyncWebServerRequest *request) {
  Serial.println("ACTION!");

  int params = request->params();
  for (int i = 0; i < params; i++) {
    AsyncWebParameter* p = request->getParam(i);
    Serial.printf("POST[%s]: %s\n", p->name().c_str(), p->value().c_str());
  }
  request->send_P(200, "text/html", index_html);
}

void setup() {
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  if (WiFi.waitForConnectResult() != WL_CONNECTED) {
    Serial.println("WiFi issue");
    while (true) yield();
  }

  Serial.print("Connect to: http://"); Serial.println(WiFi.localIP());

  server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
    request->send_P(200, "text/html", index_html);
  });
  
  server.on("/action", HTTP_POST, action);
  
  server.begin();
}

void loop() {}
1 Like

Thanks a lot!

.ino

#include <WiFi.h>
#include <ESPAsyncWebServer.h>
#include <SPIFFS.h>
#include <painlessMesh.h>

const char* ssid = "Wireless Controller";
const char* password = "12345678";

// User stub
void sendMessage() ; // Prototype so PlatformIO doesn't complain

Task taskSendMessage( TASK_SECOND * 1 , TASK_FOREVER, &sendMessage );

void sendMessage() {
  taskSendMessage.setInterval( random( TASK_SECOND * 1, TASK_SECOND * 5 ));
}

AsyncWebServer server(80);

IPAddress IP(192, 168, 1, 1);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);



void notFound(AsyncWebServerRequest *request) {
    request->send(404, "text/plain", "Not found");
}

void action(AsyncWebServerRequest *request)
{
  Serial.println("ACTION!");

  int params = request->params();
  for (int i = 0; i < params; i++)
  {
    AsyncWebParameter* p = request->getParam(i);
    Serial.printf("POST[%s]: %s\n", p->name().c_str(), p->value().c_str());
  }
  request->send(SPIFFS, "/index.html", String(), false);
}


void setup()
{
  Serial.begin(115200);

  // Initialize SPIFFS
  if (!SPIFFS.begin(true))
  {
    Serial.println("An Error has occurred while mounting SPIFFS");
    return;
  }


  WiFi.softAP(ssid, password);
  delay(500);
  WiFi.softAPConfig(IP, gateway, subnet);
  IPAddress IP = WiFi.softAPIP();
  Serial.print("AP IP address: ");
  Serial.println(IP);




  server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) 
  {
    request->send(SPIFFS, "/index.html", String(), false);  
  });




  server.on("/action", HTTP_POST, action);

      


  
  server.onNotFound(notFound);

  server.begin();
}

void loop() {}

.html

<!DOCTYPE html>
<html>
<body>

  <h1>Menu 1</h1>

<form action='action'  method="post"> 

  <p><button type="submit" name="circle" value="6">Circle</button></p>
  <p><button type="submit" name="square" value="4">Square</button></p>

</form>

</body>
</html>

What's the difference between class="submit" and type="submit"?

The <input> tag specifies an input field where the user can enter data and can be displayed in several ways, depending on the type standard attribute. See HTML input type Attribute

The HTML class attribute is used to specify a class for any HTML element and is often used to point to a class name in a style sheet.

Is there a way to get this function to work with the GET method instead of POST?

The web-server keeps crashing when I try to submit three parameters. So I want to try to submit two parameters on the first (index) page, and a final parameter on a second (patternSelection) page:

index.html

<!DOCTYPE html>
<html>

<body>

<!-- Get method (or use post method)-->
	
<form action="/patternSelection.html" method="get"> 

<!-- Select tag for size -->

		<label for="size" style="font-size: 22px;">Size:</label>

		<select name="size" id="size" style="font-size: 22px;">
		  <option value="1"> 1   </option>
		  <option value="2"> 1/2 </option> 
			</select>

<!-- Select tag for speed -->

		<p><label for="speed" style="font-size: 22px;">Speed:</label>
		
		<select name="speed" id="speed" style="font-size: 24px">
		  <option value="1"> 		  Slow </option>
		  <option value="2" selected> Regular </option>
		</select></p>

	<p><a href="/patternSelection.html"><button type="submit">Shape Selection</button></a></p>

</form>

</body>
</html>

patternSelection.html

!DOCTYPE html>
<html>
<body> 

<form action="/index.html" method="get"> 

  	<img src="1circle.png" style="max-width:100%">
  	<p><button type="submit" name="shape" value="1">1. Circle</button></p>
  	<img src="1square.png" style="max-width:100%">
  	<p><button type="submit" name="shape" value="1">2. Square</button></p>

</form>

</body>
</html>

.ino

In void setup:

server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
    request->send(SPIFFS, "/index.html", "text/html", false);
  });
  
  server.on("/patternSelection.html", HTTP_GET, [](AsyncWebServerRequest * request) {
    request->send(SPIFFS, "patternSelection.html", "text/html", false);
  });

  server.on("/patternSelection", HTTP_GET, action1); // submit and move to patternSelection

  server.on("/index", HTTP_GET, action2); // submit and return to index

Functions

void action1(AsyncWebServerRequest *request)
{
  Serial.println("ACTION!");

  int params = request->params(); // amount of params
  for (int i = 0; i < params; i++)
  {
    AsyncWebParameter* p = request->getParam(i);
    Serial.printf("POST[%s]: %s\n", p->name().c_str(), p->value().c_str());     
  }

  
  request->send(SPIFFS, "/patternSelection.html", "text/html", false);
}

void action2(AsyncWebServerRequest *request)
{
  Serial.println("ACTION!");

  int params = request->params(); // amount of params
  for (int i = 0; i < params; i++)
  {
    AsyncWebParameter* p = request->getParam(i);
    Serial.printf("POST[%s]: %s\n", p->name().c_str(), p->value().c_str());     
  }

  
  request->send(SPIFFS, "/index.html", "text/html", false);
}

Errors happens now:

[...] xtensa-esp32-elf/bin/ld.exe: C:\Users\user\AppData\Local\Temp\arduino_build_128752\libraries\ESPAsyncWebServer\WebAuthentication.cpp.o: in function `getMD5(unsigned char*, unsigned short, char*)':

C:\Users\user\Documents\Arduino\libraries\ESPAsyncWebServer\src/WebAuthentication.cpp:73: undefined reference to `mbedtls_md5_starts'
collect2.exe: error: ld returned 1 exit status

I tried modifying WebAuthentication.cpp recommended here: compilation error with ESP 2.01 library compilation erreur WebAuthentication.cpp:73: undefined reference to mbedtls_md5_starts' - bytemeta
and, I think, here: WebAuthentication.cpp:73: undefined reference to `mbedtls_md5_starts' · Issue #1147 · me-no-dev/ESPAsyncWebServer · GitHub

The same errors result.

Edit: I just found the current version on GitHub has the new parts. I just deleted the libraries and re-installed. It now works!

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.