ESP8266(ESP-01, ESP-01S) 웹서버 만들기, Html 출력하기
이전 글(ESP 웹 서버에 문자 출력하기)에 이어서 이번에는 html 코드를 출력해보도록 하겠습니다. 마찬가지로 이를 하기 위해 적절한 예시가 있습니다. 예제 - ESP8266WebServer - PostServer를 선택해 줍니다.
이 예제는 ESP의 웹서버에 Post 요청을 하는 내용이 포함되어 있습니다. Post는 서버에 요청하는 방식 중 하나이며, 서버에 있는 어떤 리소스들을 변경, 생성하기 위함입니다. 당장 이해가 안 된다면, 예제를 차근차근 진행해주시기 바랍니다.
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#endif
const char* ssid = STASSID;
const char* password = STAPSK;
ESP8266WebServer server(80);
const int led = LED_BUILTIN;
const String postForms = "<html>\
<head>\
<title>ESP8266 Web Server POST handling</title>\
<style>\
body { background-color: #cccccc; font-family: Arial, Helvetica, Sans-Serif; Color: #000088; }\
</style>\
</head>\
<body>\
<h1>POST plain text to /postplain/</h1><br>\
<form method=\"post\" enctype=\"text/plain\" action=\"/postplain/\">\
<input type=\"text\" name=\'{\"hello\": \"world\", \"trash\": \"\' value=\'\"}\'><br>\
<input type=\"submit\" value=\"Submit\">\
</form>\
<h1>POST form data to /postform/</h1><br>\
<form method=\"post\" enctype=\"application/x-www-form-urlencoded\" action=\"/postform/\">\
<input type=\"text\" name=\"hello\" value=\"world\"><br>\
<input type=\"submit\" value=\"Submit\">\
</form>\
</body>\
</html>";
void handleRoot() {
digitalWrite(led, 1);
server.send(200, "text/html", postForms);
digitalWrite(led, 0);
}
void handlePlain() {
if (server.method() != HTTP_POST) {
digitalWrite(led, 1);
server.send(405, "text/plain", "Method Not Allowed");
digitalWrite(led, 0);
} else {
digitalWrite(led, 1);
server.send(200, "text/plain", "POST body was:\n" + server.arg("plain"));
digitalWrite(led, 0);
}
}
void handleForm() {
if (server.method() != HTTP_POST) {
digitalWrite(led, 1);
server.send(405, "text/plain", "Method Not Allowed");
digitalWrite(led, 0);
} else {
digitalWrite(led, 1);
String message = "POST form was:\n";
for (uint8_t i = 0; i < server.args(); i++) {
message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
}
server.send(200, "text/plain", message);
digitalWrite(led, 0);
}
}
void handleNotFound() {
digitalWrite(led, 1);
String message = "File Not Found\n\n";
message += "URI: ";
message += server.uri();
message += "\nMethod: ";
message += (server.method() == HTTP_GET) ? "GET" : "POST";
message += "\nArguments: ";
message += server.args();
message += "\n";
for (uint8_t i = 0; i < server.args(); i++) {
message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
}
server.send(404, "text/plain", message);
digitalWrite(led, 0);
}
void setup(void) {
pinMode(led, OUTPUT);
digitalWrite(led, 0);
Serial.begin(115200);
WiFi.begin(ssid, password);
Serial.println("");
// Wait for connection
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
if (MDNS.begin("esp8266")) {
Serial.println("MDNS responder started");
}
server.on("/", handleRoot);
server.on("/postplain/", handlePlain);
server.on("/postform/", handleForm);
server.onNotFound(handleNotFound);
server.begin();
Serial.println("HTTP server started");
}
void loop(void) {
server.handleClient();
}
전체 코드입니다. 대부분은 이전에 작성된 글에서 설명이 되었기 때문에 중복되는 부분은 생략하고 추가된 부분만을 설명드리도록 하겠습니다.
const String postForms = "<html>\
<head>\
<title>ESP8266 Web Server POST handling</title>\
<style>\
body { background-color: #cccccc; font-family: Arial, Helvetica, Sans-Serif; Color: #000088; }\
</style>\
</head>\
<body>\
<h1>POST plain text to /postplain/</h1><br>\
<form method=\"post\" enctype=\"text/plain\" action=\"/postplain/\">\
<input type=\"text\" name=\'{\"hello\": \"world\", \"trash\": \"\' value=\'\"}\'><br>\
<input type=\"submit\" value=\"Submit\">\
</form>\
<h1>POST form data to /postform/</h1><br>\
<form method=\"post\" enctype=\"application/x-www-form-urlencoded\" action=\"/postform/\">\
<input type=\"text\" name=\"hello\" value=\"world\"><br>\
<input type=\"submit\" value=\"Submit\">\
</form>\
</body>\
</html>";
postForms라는 String 자료형의 변수입니다. 이 String 변수에는 html 코드들이 문자열로 저장되어 있습니다. 한줄로 작성되지 않고, \ 기호를 이용하여 줄 바꿈을 하면서 작성되어 있습니다.
도중에 \" 라고 표시된 부분이 있습니다. 이는 "를 String 변수가 끝나는 것으로 해석하지 말고, " 자체를 문자 하나로 인식하라는 표시입니다.
여기에서 살펴봐야 할 것은 <form method=\"post\" enctype=\"text/plain\" action=\"/postplain/\">\ 부분입니다. form은 웹페이지에서 입력 양식을 뜻합니다. 로그인 창이나 뭔가 정보를 입력하는 창이라고 보시면 됩니다. 실제 코드를 업로드하면, 아래와 같은 페이지가 나타납니다.
예제의 form에는 각각의 속성이 설정되어 있습니다 method, enctype, action을 설정하였습니다.
- method : 폼 전송 방식, 대표적으로 Post, Get이 있습니다.
- enctype : 인코딩 타입(encoding type)을 설정합니다. application/x-www-form-urlencoded, multipart/form-data, text/plain 방식이 있습니다.
- action : 폼이 전송되어 처리되는 url이라고 보시면 됩니다. 첫 번째 form의 action 은 /postplain/ 임으로 192.168.0.18/postplain 에서 결과가 나타나게 됩니다.
이제 /postplain에서 무언가가 처리될 수 있도록 하는 함수들이 나타납니다.
void handleRoot() {
digitalWrite(led, 1);
server.send(200, "text/html", postForms);
digitalWrite(led, 0);
}
이제 이 html 데이터를 포함한 String 변수를 서버에 보내야 합니다. handleRoot 라는 함수에서 그 역할을 수행합니다. 보내는 함수에서 2번째 매개변수가 text/html 인 것이 이전 글과의 차이점입니다.
void handlePlain() {
if (server.method() != HTTP_POST) {
digitalWrite(led, 1);
server.send(405, "text/plain", "Method Not Allowed");
digitalWrite(led, 0);
} else {
digitalWrite(led, 1);
server.send(200, "text/plain", "POST body was:\n" + server.arg("plain"));
digitalWrite(led, 0);
}
}
method가 HTTP_POST가 아니라면 405를 와 허용되지 않는다는 메세지를 띄웁니다.
HTTP_POST라면, 특정 문자열 메세지를 서버에 보냅니다. server.arg("plain")은 POST body를 가져옵니다. arg는 argument의 약자입니다.
void handleForm() {
if (server.method() != HTTP_POST) {
digitalWrite(led, 1);
server.send(405, "text/plain", "Method Not Allowed");
digitalWrite(led, 0);
} else {
digitalWrite(led, 1);
String message = "POST form was:\n";
for (uint8_t i = 0; i < server.args(); i++) {
message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
}
server.send(200, "text/plain", message);
digitalWrite(led, 0);
}
}
handleForm 함수에는 반복문이 있습니다. argument의 개수를 알 수 있는 server.args()로 개수만큼 argument의 이름과 값을 message 변수에 저장합니다. 모두 저장이 완료되면, 서버에 보냅니다.
이후의 코드들은 이전글과 내용이 유사한 부분이 많기 때문에 생략하고, 업로드를 진행해보겠습니다.
업로드를 진행하고 난 뒤의 ip 주소로 들어가게 되면, 위와 같이 나타납니다. submit 버튼이 두 개가 있습니다. 첫 번째 submit 버튼은 /postplain url로 이어지며, handlePlain 함수가 실행됩니다. 결과로는 아래와 같이 나타납니다.
두 번째 submit 버튼은 /postform url로 이어지며, handleForm 함수가 실행됩니다. 결과로는 아래와 같이 나타납니다.
'개발 > ESP32, ESP8266' 카테고리의 다른 글
ESP8266(ESP-01, ESP-01S) wifi client, 서버로 부터 데이터 받기 (0) | 2022.11.11 |
---|---|
ESP8266(ESP-01, ESP-01S) SSE, 서버에서 클라이언트에게 데이터 전송 (2) | 2022.10.30 |
ESP8266(ESP-01, ESP-01S) 웹서버 만들기, 간단한 문자 출력 (0) | 2022.10.23 |
ESP8266(ESP-01, ESP-01S) 와이파이 리스트 검색 (0) | 2022.10.09 |
ESP8266(ESP-01, ESP-01S) 개요, 업로드하기 (0) | 2022.10.04 |