ESP8266服务器解析客户端传输的JSON文件删除列表失败问题排查
问题分析与解决方案
你的问题核心在于对JSON结构的解析处理完全不匹配,我们一步步拆解问题并给出修复方案:
首先看客户端实际发送的JSON内容:
[{"fileID_0":"/settings.json"},{"fileID_1":"/tdata.js"},{"fileID_2":"/scripts.js"}]
这是一个由多个单键值对对象组成的数组,既不是单一对象,也不是字符串数组——这是你两次解析失败的根本原因。
原代码的具体问题
- 第一次尝试:强行把根节点转成
JsonObject,但实际根是数组,所以遍历自然拿不到任何内容; - 第二次尝试:虽然正确转成了
JsonArray,但遍历数组时错误地把每个元素当成字符串调用as<const char*>,可每个元素本身是JsonObject,不是字符串,因此输出为空。
修正后的服务器端代码
我们需要先遍历数组,再处理每个数组元素内部的对象:
void deleteFiles() { String input = webserver.arg("plain"); Serial.println(input); DynamicJsonDocument doc(2048); DeserializationError err = deserializeJson(doc, input); // 先处理反序列化错误 if (err) { Serial.println(F("deserializeJson() failed with code ")); Serial.println(err.f_str()); webserver.send(400, "text/plain", "Invalid JSON"); // 返回明确的错误响应 return; } // 确认根节点是数组类型 if (!doc.is<JsonArray>()) { Serial.println(F("Root is not an array!")); webserver.send(400, "text/plain", "Root must be an array"); return; } JsonArray arr = doc.as<JsonArray>(); for(JsonVariant v : arr) { // 每个数组元素是一个JsonObject,遍历它的键值对 JsonObject obj = v.as<JsonObject>(); for (JsonPair p : obj) { Serial.print("File ID: "); Serial.println(p.key().c_str()); Serial.print("File name: "); Serial.println(p.value().as<const char*>()); // 这里可以添加实际的文件删除逻辑,比如: // if (SPIFFS.remove(p.value().as<const char*>())) { // Serial.print("Successfully deleted: "); // Serial.println(p.value().as<const char*>()); // } else { // Serial.print("Failed to delete: "); // Serial.println(p.value().as<const char*>()); // } } } webserver.send(200, "text/plain", "Delete request processed"); // 返回成功响应 }
额外优化建议
其实你的客户端没必要把每个文件名包装成单独的对象,直接发送纯文件名数组会大幅简化前后端逻辑:
// 客户端修改deleteFiles函数的逻辑 function deleteFiles() { // 直接过滤出标记为删除的文件名,组成数组 let deleteFileList = fileList.filter(file => file.marked).map(file => file.name); if (deleteFileList.length > 0) { var xhttp = new XMLHttpRequest(); var formData = JSON.stringify(deleteFileList); xhttp.open("POST", "/deleteFiles"); xhttp.send(formData); } }
此时发送的JSON会变成更简洁的格式:["/settings.json", "/tdata.js", "/scripts.js"],服务器端处理可以进一步简化:
void deleteFiles() { String input = webserver.arg("plain"); Serial.println(input); DynamicJsonDocument doc(2048); DeserializationError err = deserializeJson(doc, input); if (err) { Serial.println(F("deserializeJson() failed with code ")); Serial.println(err.f_str()); webserver.send(400, "text/plain", "Invalid JSON"); return; } JsonArray arr = doc.as<JsonArray>(); for(JsonVariant v : arr) { const char* fileName = v.as<const char*>(); Serial.print("File to delete: "); Serial.println(fileName); // 执行文件删除操作 // SPIFFS.remove(fileName); } webserver.send(200, "text/plain", "Delete request processed"); }
内容的提问来源于stack exchange,提问作者PythonStemmi
相关产品推荐
相关产品推荐

