In HTML, <a href= is the start of a link. Clicking it is the same as using a bookmark, or typing the URL directly: it makes a request using the HTTP method/verb GET, effectively the default method.
If you follow that (mediocre) linked tutorial
String request = client.readStringUntil('\r');
Serial.println(request);
will first print (without the handy syntax highlighting shown here)
GET / HTTP/1.1
for the initial page load, and then
GET /LED=ON HTTP/1.1
when you click the ON button. This first line of the request is the start-line or request-line, comprising
- the method/verb
- URI-path, always starting with a slash
- HTTP version
The code blindly searches
if (request.indexOf("/LED=ON") != -1) {
the line, meaning it would also turn on if you request
DELETE /blah/LED=ONyx HTTP/1.1
but for a (mediocre) tutorial... eh. More egregious is representing the same web page resource as three different paths.
For the web page to do a POST instead, the quickest/simplest way is with a form
<form method="POST">
<button name="LED" value="ON">ON</button>
<button name="LED" value="OFF">OFF</button>
</form>
However, this has a drawback: now if you refresh, the browser will prompt you to "Confirm Form Resubmission". This is because the current page is the result of a POST, and that might be for something like making a purchase. You wouldn't want a refresh to buy something again. Also the prompt may just be plain confusing.
The solution is with the Post/Redirect/Get pattern:
POST the request that changes something (that you don't want repeated with a refresh)
- The server does not respond directly (with an HTML page) but instead returns a redirect, commanding the browser to load something else
- That something else (in this case) would be the same page originally requested with
GET, which is safe to load repeatedly, and would now show the updated status
This also clearly separates the kind of request for a given resource, which in the tutorial, is the root page / -- perfectly fine for a simple Arduino controller page
GET returns the status, and includes buttons to change things
- response
200 OK with HTML
POST changes the status
- response
303 See Other with the Location header
If you have exactly one page, then you're no longer parsing/searching the URI-path; you can act solely upon the method/verb, and by parsing the POST body.