ESP8266/ESP32 Arduino框架 web页面与C代码的数据交换方法

最近一直在研究esp8266,对一个问题非常不解:怎样才能让前端(HTML)与后端(c++代码)进行数据通信。在网上找了很多示例代码,发现很多交换数据的方法都是在c语言中进行HTML语句的组合,再发送给客户端进行显示的:

void sendInfo() {
    
    
  String str;
  FSInfo fs_info;
  LittleFS.info(fs_info);
  str += "<h1>系统信息</h1>";
  str += "<br>系统可用内存:" + (String)(ESP.getFreeHeap() / 1024) + "KB";
  str += "<br>CPU频率:" + (String)ESP.getCpuFreqMHz() + "MHz";
  str += "<br>LittleFS总容量:" + (String)(fs_info.totalBytes / 1024) + "KB";
  str += "<br>LittleFS可用容量:" +
         (String)((fs_info.totalBytes - fs_info.usedBytes) / 1024) + "KB";
  str += "<br>已连接的客户端数量:" + (String)WiFi.softAPgetStationNum();
  server.send(200, F("text/html"), str);
}

显而易见,这样的方法好处就是简单方便,适合少量数据的发送与显示。
但是,如果一次性需要发送大量数据,或者网页设计的很复杂,这种拼接数据的方法就不适用了。
那么有没有什么办法,既能在保证网页内容不被更改的情况下又能交换数据呢?
答案是:有!

html代码

如果曾经学习过html/js,那么看这句话就可以了:利用ajax来交换数据!
如果没有学习过也没关系,马上去w3cschool学习ajax也是可以的!
不多说,直接贴代码:

<html>
<head>
    <meta charset="utf-8" />
</head>
<script>
    setInterval(() => {
     
     
        getData();
    }, 1000);
    function getData() {
     
     
        var xhttp = new XMLHttpRequest();
        xhttp.onreadystatechange = function () {
     
     
            if (this.readyState == 4 && this.status == 200) {
     
     
                console.log(this.responseText);
                document.getElementById("data").innerHTML = this.responseText;
            }
        }
        xhttp.open("GET", "/getData");
        xhttp.send();
    }
    function sendData() {
     
     
        console.log("button clicked");
        var xhttp = new XMLHttpRequest();
        xhttp.open("POST", "/sendData");
        xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        xhttp.send("data="+document.getElementById("sometext").value);
    }
</script>
<body>
    <h1>WebInteractiveTest</h1>
    <p id="data">Loading...</p>
    <br />
    <input id="sometext" type='text' name='PASSWORD' placeholder=''>
</body>
<button onclick="sendData()">SendData</button>
</html>

Arduino代码

#include <ESP8266WebServer.h>
ESP8266WebServer server(80);
const char* webpage PROGMEM =
    "<meta charset=utf-8><meta name=\'viewport\' "
    "content=\'width=device-width,initial-scale=1\'><script>function "
    "getData(){var e=new "
    "XMLHttpRequest;e.onreadystatechange=function(){4==this.readyState&&200=="
    "this.status&&(console.log(this.responseText),document.getElementById("
    "\"data\").innerHTML=this.responseText)},e.open(\"GET\",\"/"
    "getData\"),e.send()}function sendData(){console.log(\"button "
    "clicked\");var e=new "
    "XMLHttpRequest;e.open(\"POST\",\"/"
    "sendData\"),e.setRequestHeader(\"Content-type\",\"application/"
    "x-www-form-urlencoded\"),e.send(\"data=\"+document.getElementById("
    "\"sometext\").value)}setInterval(()=>{getData()},1e3)</"
    "script><h1>WebInteractiveTest</h1><p id=data>Loading...</p><br><input "
    "id=sometext name=PASSWORD placeholder=\"\"><button "
    "οnclick=sendData()>SendData</button>";
void handleIndex() {
    
     server.send(200, F("text/html"), webpage); }
void getData() {
    
    
  Serial.printf("Raw Arguments:%s\n", server.arg(F("plain")).c_str());
  server.send(200);
}
void sendData() {
    
    
  static int data;
  server.send(200, F("text/plain"), (String)data);
  data++;
}
void setup() {
    
    
  Serial.begin(115200);
  WiFi.mode(WIFI_AP);
  WiFi.softAP(F("ESP_TEST"));//热点:ESP_TEST,无密码
  server.on("/", handleIndex);
  server.on(F("/getData"), sendData);
  server.on(F("/sendData"), getData);
  server.begin();
}
void loop() {
    
     server.handleClient(); }

代码解析

(其实是很简单的代码,但是以防万一以后自己看不懂了,还是做个注释比较好)
html部分,js每隔一秒向/getData请求一个数据,并将数据打印到控制台上,且将<id="data">的标签中的内容改为接受到的数据。
c++部分,自增data变量且发送
发送数据则采用POST方法,ajax post数据到/sendData处,c++部分接受并打印到串口。

猜你喜欢

转载自blog.csdn.net/CNflysky/article/details/115441893