开发者问题收集

获取一次输出后出现错误:“未捕获 TypeError:无法在 xhttp.onreadystatechange 中设置 null 属性(设置‘innerHTML’)”

2023-12-05
57

我正在使用 ESP8266 (NodeMCU) 从传感器 (DHT11 和 MQ4) 获取数据 (温度、湿度和气体) 并在网站上显示它们,视图中一切正常,但是当我转到控制台时,我看到此错误:

"(index):18 Uncaught TypeError: Cannot set properties of null (setting 'innerHTML')
    at xhttp.onreadystatechange ((index):18:56)
xhttp.onreadystatechange @ (index):18
XMLHttpRequest.send (async)
updateData @ (index):24
setInterval (async)
(anonymous) @ (index):26 "

这是我正在使用的 Arduino IDE 代码:

include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include "DHTesp.h"

#define DHTpin 14    //D5 of NodeMCU is GPIO14
DHTesp dht;



const char* ssid = "Tasnim";       // Enter SSID here
const char* password = "peara2304";  // Enter Password here

ESP8266WebServer server(80);




// MQ-4 Gas Sensor
uint8_t MQ4Pin = A0;

float Temperature = dht.getTemperature();  
 float Humidity = dht.getHumidity();        
 float  GasValue = analogRead(MQ4Pin);       

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

  dht.setup(DHTpin, DHTesp::DHT11);
  pinMode(MQ4Pin, INPUT);



  Serial.println("Connecting to ");
  Serial.println(ssid);

  // Connect to your local Wi-Fi network
  WiFi.begin(ssid, password);

  // Check Wi-Fi connection
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected..!");
  Serial.print("Got IP: ");
  Serial.println(WiFi.localIP());

  server.on("/", HTTP_GET, handle_OnConnect);
  server.on("/data", HTTP_GET, handle_Data);
  server.onNotFound(handle_NotFound);

  server.begin();
  Serial.println("HTTP server started");
}

void loop() {
  server.handleClient();
}

void handle_OnConnect() {
 float Temperature = dht.getTemperature();  
 float Humidity = dht.getHumidity();        
 float  GasValue = analogRead(MQ4Pin);       

  server.send(200, "text/html", SendHTML(Temperature, Humidity, GasValue));
}

void handle_Data() {
  String data = "{\"temperature\":" + String(Temperature) +
                ",\"humidity\":" + String(Humidity) +
                ",\"gasValue\":" + String(GasValue) + "}";
  server.send(200, "application/json", data);
}

void handle_NotFound() {
  server.send(404, "text/plain", "Not found");
}

String SendHTML(float Temperaturestat, float Humiditystat, float GasValueStat) {
  String ptr = "<!DOCTYPE html> <html>\n";
  ptr += "<head><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n";
  ptr += "<title>ESP8266 Weather and Gas Report</title>\n";
  ptr += "</head>\n";
  ptr += "<body>\n";
  ptr += "<div id=\"webpage\">\n";
  ptr += "<h1>ESP8266 NodeMCU Weather and Gas Report</h1>\n";
  ptr += "<p>Temperature: " + String(Temperaturestat) + "°C</p>\n";
  ptr += "<p>Humidity: " + String(Humiditystat) + "%</p>\n";
  ptr += "<p>Gas Value: " + String(GasValueStat) + "</p>\n";
  ptr += "</div>\n";
  ptr += "<script>\n";
  ptr += "function updateData() {\n";
  ptr += "  var xhttp = new XMLHttpRequest();\n";
  ptr += "  xhttp.onreadystatechange = function() {\n";
  ptr += "    if (this.readyState == 4 && this.status == 200) {\n";
  ptr += "      var data = JSON.parse(this.responseText);\n";
  ptr += "      document.getElementById('temperature').innerHTML = 'Temperature: ' + data.temperature + '°C';\n";
  ptr += "      document.getElementById('humidity').innerHTML = 'Humidity: ' + data.humidity + '%';\n";
  ptr += "      document.getElementById('gasValue').innerHTML = 'Gas Value: ' + data.gasValue;\n";
  ptr += "    }\n";
  ptr += "  };\n";
  ptr += "  xhttp.open('GET', '/data', true);\n";
  ptr += "  xhttp.send();\n";
  ptr += "}\n";
  ptr += "setInterval(updateData, 1000);\n";
  ptr += "function autoRefresh(){";
  ptr += "window.location = window.location.href;";
  ptr += "}\n";
  ptr += "setInterval('autoRefresh()',100000)";
  ptr += "</script>\n";
  ptr += "</body>\n";
  ptr += "</html>\n";
  return ptr;
}

在此处输入图像描述

我正在尝试以 API 的形式获取数据以供使用另一台服务器调用,因此我需要控制台上的数据。 请帮帮我,我是这项工作的初学者。

2个回答

您忘记在生成的 HTML 中输入 ID:

  ptr += "<p id='temperature'>Temperature: " + String(Temperaturestat) + "°C</p>\n";
  ptr += "<p id='humidity'>Humidity: " + String(Humiditystat) + "%</p>\n";
  ptr += "<p id='gasValue'>Gas Value: " + String(GasValueStat) + "</p>\n";
Barmar
2023-12-05

发现错误:

  • 忘记将 ID 放入 html 中,以便 JS 进行更改:

    ptr += " document.getElementById('Temperature').innerHTML = 'Temperature: ' + data.Temperature + '°C';\n";
    ptr += " document.getElementById('Humidity').innerHTML = 'Humidity: ' + data.Humidity + '%';\n";
    ptr += " document.getElementById('gasValue').innerHTML = 'Gas Value: ' + data.gasValue;\n";
    
  • 传感器读数是全局声明的,其值在设置期间仅更新一次,导致静态值被重复发送而不更新,从而更改函数:

    void handle_Data() { float Temperature = dht.getTemperature(); float Humidity = dht.getHumidity(); float GasValue = analogRead(MQ4Pin);

    String data = "{\"Temperature\":" + String(Temperature) +
    ",\"Humidity\":" + String(Humidity) +
    ",\"gasValue\":" + String(GasValue) + "}";
    server.send(200, "application/json", data);
    

    >

替换这些代码即可解决问题。

完整工作代码(更新后):

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include "DHTesp.h"

#define DHTpin 14    //D5 of NodeMCU is GPIO14
DHTesp dht;

// Uncomment one of the lines below for whatever DHT sensor type you're using!

//#define DHTTYPE DHT21   // DHT 21 (AM2301)
//#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321

/* Put your SSID & Password */
const char* ssid = "Tasnim";       // Enter SSID here
const char* password = "peara2304";  // Enter Password here

ESP8266WebServer server(80);




// MQ-4 Gas Sensor
uint8_t MQ4Pin = A0;

float Temperature = dht.getTemperature();  // Gets the values of the temperature
 float Humidity = dht.getHumidity();        // Gets the values of the humidity
 float  GasValue = analogRead(MQ4Pin);       // Gets the values of the gas sensor

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

  dht.setup(DHTpin, DHTesp::DHT11);
  pinMode(MQ4Pin, INPUT);



  Serial.println("Connecting to ");
  Serial.println(ssid);

  // Connect to your local Wi-Fi network
  WiFi.begin(ssid, password);

  // Check Wi-Fi connection
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected..!");
  Serial.print("Got IP: ");
  Serial.println(WiFi.localIP());

  server.on("/", HTTP_GET, handle_OnConnect);
  server.on("/data", HTTP_GET, handle_Data);
  server.onNotFound(handle_NotFound);

  server.begin();
  Serial.println("HTTP server started");
}

void loop() {
  server.handleClient();
}

void handle_OnConnect() {
 float Temperature = dht.getTemperature();
  float Humidity = dht.getHumidity();
  float GasValue = analogRead(MQ4Pin);

  server.send(200, "text/html", SendHTML(Temperature, Humidity, GasValue));
}

void handle_Data() {
  float Temperature = dht.getTemperature();
  float Humidity = dht.getHumidity();
  float GasValue = analogRead(MQ4Pin);

  String data = "{\"Temperature\":" + String(Temperature) +
                ",\"Humidity\":" + String(Humidity) +
                ",\"gasValue\":" + String(GasValue) + "}";
  server.send(200, "application/json", data);
}

void handle_NotFound() {
  server.send(404, "text/plain", "Not found");
}

String SendHTML(float Temperaturestat, float Humiditystat, float GasValueStat) {
  String ptr = "<!DOCTYPE html> <html>\n";
  ptr += "<head><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n";
  ptr += "<title>ESP8266 Weather and Gas Report</title>\n";
  ptr += "</head>\n";
  ptr += "<body>\n";
  ptr += "<div id=\"webpage\">\n";
  ptr += "<h1>ESP8266 NodeMCU Weather and Gas Report</h1>\n";
  ptr += "<p id='Temperature'>Temperature: " + String(Temperaturestat) + "°C</p>\n";
  ptr += "<p id='Humidity'>Humidity: " + String(Humiditystat) + "%</p>\n";
  ptr += "<p id='gasValue'>Gas Value: " + String(GasValueStat) + "</p>\n";
  ptr += "</div>\n";
  ptr += "<script>\n";
  ptr += "function updateData() {\n";
  ptr += "  var xhttp = new XMLHttpRequest();\n";
  ptr += "  xhttp.onreadystatechange = function() {\n";
  ptr += "    if (this.readyState == 4 && this.status == 200) {\n";
  ptr += "      var data = JSON.parse(this.responseText);\n";
  ptr += "      document.getElementById('Temperature').innerHTML = 'Temperature: ' + data.Temperature + '°C';\n";
  ptr += "      document.getElementById('Humidity').innerHTML = 'Humidity: ' + data.Humidity + '%';\n";
  ptr += "      document.getElementById('gasValue').innerHTML = 'Gas Value: ' + data.gasValue;\n";
  ptr += "    }\n";
  ptr += "  };\n";
  ptr += "  xhttp.open('GET', '/data', true);\n";
  ptr += "  xhttp.send();\n";
  ptr += "}\n";
  ptr += "setInterval(updateData, 1000);\n";
  ptr += "function autoRefresh(){";
  ptr += "window.location = window.location.href;";
  ptr += "}\n";
  ptr += "setInterval('autoRefresh()',100000)";
  ptr += "</script>\n";
  ptr += "</body>\n";
  ptr += "</html>\n";
  return ptr;
}
Sasuke_uchiha
2023-12-05