Serial
.
println
(
WiFi
.
localIP
());
// Send the IP address of the ESP8266 to the computer
if
(
MDNS
.
begin
(
"esp8266"
)) {
// Start the mDNS responder for esp8266.local
Serial
.
println
(
"mDNS responder started"
);
}
else
{
Serial
.
println
(
"Error setting up MDNS responder!"
);
}
server
.
on
(
"/"
,
HTTP_GET
,
handleRoot);
// Call the 'handleRoot' function when a client requests URI "/"
server
.
on
(
"/login"
,
HTTP_POST
,
handleLogin);
// Call the 'handleLogin' function when a POST request is made to URI "/login"
server
.
onNotFound
(handleNotFound);
// When a client requests an unknown URI (i.e. something other than "/"), call function
"handleNotFound"
server
.
begin
();
// Actually start the server
Serial
.
println
(
"HTTP server started"
);
}
void
loop
(
void
){
server
.
handleClient
();
// Listen for HTTP requests from clients
}
void
handleRoot() {
// When URI / is requested, send a web page with a button to toggle the LED
server
.
send
(200
,
"text/html"
,
"<form action=\"/login\" method=\"POST\"><input type=\"text\" name=\"username\"
placeholder=\"Username\"></br><input type=\"password\" name=\"password\" placeholder=\"Password\"></br><input type=\"submit\"
value=\"Login\"></form><p>Try 'John Doe' and 'password123' ...</p>"
);
}
void
handleLogin() {
// If a POST request is made to URI /login
if
(
!
server
.
hasArg
(
"username"
)
||
!
server
.
hasArg
(
"password"
)
||
server
.
arg
(
"username"
)
==
NULL
||
server
.
arg
(
"password"
)
==
NULL
) {
// If the POST request doesn't have username and password
data
server
.
send
(400
,
"text/plain"
,
"400: Invalid Request"
);
// The request is invalid, so send HTTP status 400
return
;
}
if
(server
.
arg
(
"username"
)
==
"John Doe"
&&
server
.
arg
(
"password"
)
==
"password123"
) {
// If both the username and the password are
correct
server
.
send
(200
,
"text/html"
,
"<h1>Welcome, "
+
server
.
arg
(
"username"
)
+
"!</h1><p>Login successful</p>"
);
}
else
{
// Username and password don't match
server
.
send
(401
,
"text/plain"
,
"401: Unauthorized"
);
}
}
void
handleNotFound(){
server
.
send
(404
,
"text/plain"
,
"404: Not found"
);
// Send HTTP status 404 (Not Found) when there's no handler for the URI in the
request
}
The HTML in handleRoot is:
<form action="/login" method="POST">
<input type="text" name="username" placeholder="Username"></br>
<input type="password" name="password" placeholder="Password"></br>
<input type="submit" value="Login">
</form>
<p>
Try 'John Doe' and 'password123' ...
</p>
Upload the sketch and go to http://esp8266.local/, then type 'John Doe' into the username field, and 'password123' into the password
field, and click 'Login'. You should get a welcome screen. If you leave on or both of the fields blank, you should get a 400 (Bad
Request) error. If you enter a wrong username or password, you should get a 401 (Unauthorized) error.
The data of the POST body can be accessed using
server.arg("key")
, and you can check if a specific key exists using
server.hasArg("key")
. The key name on the ESP8266 corresponds to the name argument in the HTML form on the web page.
When we get a POST request, we first check if the necessary arguments (username and password) are present. If that's not the case,
we send a 400 (Invalid Request) status.
Then we check if the credentials match 'John Doe' & 'password123'. If that's the case, we respond with a status 200 (Ok) and a
welcome page. If the username and/or password doesn't match, we send a 401 (Unauthorized) status.
Inline functions
In the previous examples, we passed
handleRoot
and
handleNotFound
to the
server.on
function as a parameter (callback function). In some
cases however, it's more readable to just write the definition of the function inline, like so:
void
setup
(){
// ...
server
.
onNotFound
([](){
server
.
send
(404
,
"text/plain"
,
"404: Not found"
);
});
}