You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ESP8266服务器解析客户端传输的JSON文件删除列表失败问题排查

问题分析与解决方案

你的问题核心在于对JSON结构的解析处理完全不匹配,我们一步步拆解问题并给出修复方案:

首先看客户端实际发送的JSON内容:

[{"fileID_0":"/settings.json"},{"fileID_1":"/tdata.js"},{"fileID_2":"/scripts.js"}]

这是一个由多个单键值对对象组成的数组,既不是单一对象,也不是字符串数组——这是你两次解析失败的根本原因。

原代码的具体问题

  1. 第一次尝试:强行把根节点转成JsonObject,但实际根是数组,所以遍历自然拿不到任何内容;
  2. 第二次尝试:虽然正确转成了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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 00:27:38