你好吗?.
我正在制作一个应用程序,其中 ESP32 用作 Web 服务器,目前我有一个网页来配置设备。
在此页面中有一个
<form>
元素,一旦按下提交按钮,配置就会发送到ESP32,我知道数据已发送,因为我正在使用wireshark观看它,如下图所示
我知道ESP32正在接收POST请求,因为我在代码中有几个println语句,所以,处理请求的代码如下
server.on("/forma-dato", HTTP_POST, [](AsyncWebServerRequest *request) {
if(!request->authenticate(usuarioHTTP, claveHTTP)) {
return request->requestAuthentication();
};
request->send(200);
Serial.println("Solicitud de carga de archivos enviada.");
ultimaPaginaCargada = "/config.html";
}, manejaJson);
回调
manejaJSON
定义如下,摘自本页
void manejaJson(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final) {
Serial.println("Recibiendo configuración de la dirección IP ." + request->client()->remoteIP().toString() + " " + request->url());
if(!filename) {
Serial.println("No hay archivo.");
}
if(!index) {
request->_tempFile = SPIFFS.open("/" + filename, "w");
Serial.println("Carga Iniciada" + String(filename));
}
if(len) {
request->_tempFile.close();
Serial.println("Escribiendo archivo: " + String(filename) + ", tamaño: " + String(len));
}
if(final) {
request->_tempFile.close();
Serial.println("Carga completa: " + String(filename) + ", tamaño: " + String(index + filename));
request->redirect("/");
}
}
正如你所看到的,有几个 println 句子可以知道程序在做什么,但是 manejaJson 回调中没有任何消息被打印,所以我认为 manejaJson 回调没有被执行,此外我没有任何返回值manejaJson 和 void 定义是因为与将其定义为
ArUploadHandlerFunction
相同,如在 AsyncWebServer 库的 .on
中声明的 WebServer.cpp
定义一样。
下面是从网页发送数据的代码
if(document.getElementById("forma") != null) { // Si encuentra la forma con la id igual a "forma",
var elementoForma = document.getElementById("forma"); // extrae los valores completos.
elementoForma.addEventListener("submit", function(e) {
e.preventDefault();
var datosForma = {};
var formaDatos = new FormData(elementoForma);
for(var [k,v] of formaDatos) {
datosForma[k] = v;
}
console.log(datosForma);
var datosJson = JSON.stringify(datosForma)
console.log(datosJson);
var config = new Blob([datosJson], {type: 'application/json'});
fetch("forma-dato", {
method: "POST",
body: config
});
/*fs.writeFile('config.json', datosJson, 'utf-8', (err) => {
if(err) {
throw err;
}
console.log("Archivo guardado correctamente");
});*/
console.log(config);
/*var envioForma = new XMLHttpRequest();
envioForma.open("POST", "forma-dato", true);
envioForma.send(config);*/
});
}
正确知道数据是通过使用 fetch 方法发送的,但注释是另外两段发送数据的代码,一段使用
writefile
,另一段使用 XMLHttpRequest,现在的 writefile 不太喜欢,因为在完全离线的应用程序中使用node.js。
那么,我能做些什么来解决这个问题并能够处理传入的数据。
预先感谢您的帮助。
注意:这个问题是我之前发表的this帖子的精确副本,但电子堆栈交换中的人们建议我在这里发表帖子,因为与软件比固件更相关。
为了让他们都知道,我能够使用在互联网上找到的代码解决问题,问题似乎是用于管理传入请求的 AsyncWebServer API 的默认方法不管理正文中包含 JSON 数据的请求默认情况下。
为了管理数据,必须使用 asyncjson.h 和 arduinojson.h,代码如下
AsyncCallbackJsonWebHandler* manejadorJson = new AsyncCallbackJsonWebHandler("/forma-dato", [](AsyncWebServerRequest *request, JsonVariant &docJson) {
auto&& jsonObj = docJson.as<JsonObject>();
Serial.print("La fecha actual es :");
Serial.println((const char *) jsonObj["fecha"]);
Serial.print("El horario del domingo en la tarde es: ");
Serial.println((const char *) jsonObj["domingo-tarde-fin"]);
request->send(200);
Serial.println("Configuración recibida.");
});
server.addHandler(manejadorJson);
当然所有的打印语句都是我写的,以便能够知道数据是否被处理过。
注意:在 AsyncWebServer API 的自述文件中是一个几乎类似于下面的示例,而不是使用该行
auto&& jsonObj = docJson.as<JsonObject>()
已使用
JsonObject& jsonObj = docJson.as<JsonObject>()
用上一行(只有一个 &)编写的示例对我来说不起作用,我查看了那里,显然这句话的问题是无法引用尚未初始化的变量。
JsonObject& jsonObj = docJson.as<JsonObject>()
错误:无法将“ArduinoJson::V704PB2::JsonObject&”类型的非常量左值引用绑定到“ArduinoJson::V704PB2::detail::enable_if