Чтение файла json из SPIFFS и отображение содержащейся в нем информации на встроенной веб-странице
Я работаю над интеллектуальным ИК-приемником, который считывает ИК-сигнал, декодирует его и сохраняет эту декодированную информацию в файле json, хранящемся в SPIFFS NodeMCU. Затем эта информация отображается на встроенном веб-сервере в виде таблицы.
Теперь моя проблема заключается в том, что, хотя я правильно сохраняю информацию о сигнале в файле json (и когда я пытаюсь распечатать его в консоли, он выглядит идеально), файл сына не передается правильно на мой веб-сервер, и таблица остается пустой. Я использую jQuery для чтения файла и внесения изменений в HTML. Все файлы веб-сервера (HTML, css и JavaScript) были сначала протестированы на моем локальном компьютере с помощью примера файла Json той же структуры, что и на моем SPIFFS, поэтому я точно знаю, что проблема не в нем.
Стоит отметить, что я столкнулся с этой проблемой при разработке на своем локальном компьютере, где таблица оставалась пустой, хотя файла json не было, но она была исправлена, когда я использовал расширение Live Server в VSCode. Однако я не понимаю, является ли это проблемой, почему нет сервера для передачи файла json, когда все файлы моего веб-интерфейса правильно передаются и загружаются из SPIFFS.
Я включу часть своего кода, и, конечно же, буду признателен за любую помощь.
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WiFiMulti.h>
#include <ESP8266mDNS.h>
#include <ESP8266WebServer.h>
#include <Arduino.h>
#include <IRremoteESP8266.h>
#include <IRrecv.h>
#include <IRutils.h>
#include<FS.h> // Подключаем библиотеку SPIFFS
#include <NTPClient.h>
#include <WiFiUdp.h>
#include <ArduinoJson.h>
ESP8266WiFiMulti wifiMulti; // Создаем экземпляр класса ESP8266WiFiMulti с именем 'wifiMulti'
ESP8266WebServer server(80); // Создаем объект веб-сервера, который прослушивает HTTP-запрос на порту 80
String getContentType(String filename); // преобразовать расширение файла в тип MIME
bool handleFileRead(String path); // отправляем нужный файл клиенту (если он существует)
// Объявление переменной для хранения размера объекта JSON
//постоянная емкость size_t = JSON_OBJECT_SIZE(10);
// Создание документа JSON для хранения записи сигнала
//DynamicJsonDocument doc(capacity);
// Объявление размера массива
const size_t array_capacity = JSON_ARRAY_SIZE(16) + JSON_OBJECT_SIZE(1) + 16*JSON_OBJECT_SIZE(9);
// Создание документа JSON для хранения всех записей сигналов во вложенном массиве
DynamicJsonDocument array_doc(array_capacity);
// Создание вложенного массива JSON для хранения всех записей сигналов
JsonArray signals = array_doc.createNestedArray("signals");
// Объявление объекта JSON для хранения одной записи сигнала
JsonObject signal_entry;
// Объявление метода, который сохраняет объект JSON в файл JSON, хранящийся на SPIFFS
void saveJSON();
// Объявление метода, который печатает JSON-файл, хранящийся на SPIFFS
void printJSON();
void setup(void){
Serial.begin(115200); // Запуск последовательной связи для отправки сообщений на компьютер
delay(10);
Serial.println('\n');
Serial.println("Connecting ...");
int i = 0;
while (wifiMulti.run() != WL_CONNECTED) { // Подождите, пока сеть Wi-Fi подключится: просканируйте сети Wi-Fi и подключитесь к самой мощной из указанных выше сетей
delay(250);
Serial.print('.');
}
SPIFFS.begin(); // Запуск файловой системы SPI Flash
server.begin(); // Собственно запускаем сервер
Serial.println("HTTP server started");
server.onNotFound([]() { // Если клиент запрашивает любой URI
if (!handleFileRead(server.uri())) // отправить его, если он существует
server.send(404, "text/plain", "404: Not Found"); // в противном случае ответ с ошибкой 404 (Not Found)
});
void loop(void){
server.handleClient(); // Слушаем HTTP-запросы от клиентов
//Создание объекта JSON из документа JSON
signal_entry = signals.createNestedObject();
//Присвоение правильных значений ключам в объекте JSON
signal_entry["date"] = currentDate;
signal_entry["protocol_type"] = protocol_type;
signal_entry["bitNr_device"] = bitNr_device;
signal_entry["bitNr_op"] = bitNr_op;
signal_entry["codeDec_device"] = codeDec_device;
signal_entry["codeDec_op"] = codeDec_op;
signal_entry["codeHex_device"] = codeHex_device;
signal_entry["codeHex_op"] = codeHex_op;
signal_entry["codeBin_device"] = codeBin_device;
signal_entry["codeBin_op"] = codeBin_op;
serializeJsonPretty(signal_entry, Serial);
Serial.println("");
saveJSON();
}
}
String getContentType(String filename) { // преобразовать расширение файла в тип MIME
if (filename.endsWith(".html")) return "text/html";
else if (filename.endsWith(".css")) return "text/css";
else if (filename.endsWith(".js")) return "application/javascript";
else if (filename.endsWith(".ico")) return "image/x-icon";
return "text/plain";
}
bool handleFileRead(String path) { // отправляем нужный файл клиенту (если он существует)
Serial.println("handleFileRead: " + path);
if (path.endsWith("/")) path += "index.html"; // Если запрашивается папка, отправляем индексный файл
String contentType = getContentType(path); // Получаем MIME-тип
if (SPIFFS.exists(path)) { // Если файл существует
File file = SPIFFS.open(path, "r"); // Открой это
size_t sent = server.streamFile(file, contentType); // И отправляем клиенту
file.close(); // Затем снова закрываем файл
return true;
}
Serial.println("\tFile Not Found");
return false; // Если файл не существует, возвращаем false
}
void saveJSON(){
File jsonFile = SPIFFS.open("signals.json", "w");
if (serializeJsonPretty(array_doc, jsonFile) == 0) {
Serial.println("Failed to write to file");
}
jsonFile.close();
}
void printJSON(){
uint8_t* pBuffer;
File testFile = SPIFFS.open("signals.json", "r");
if(testFile){
unsigned int fileSize = testFile.size();
pBuffer = (uint8_t*)malloc(fileSize + 1);
testFile.read(pBuffer, fileSize);
pBuffer[fileSize] = '\0';
Serial.println((char*)pBuffer); // Печатаем файл на последовательный монитор.
testFile.close();
}
else{
Serial.println("Failed to read to file");
}
free(pBuffer);
}
@Mo'men Alaswad, 👍0
Обсуждение1 ответ
Помимо несколько странной проблемы с вложенностью loop() внутрь setup() (которую я отнесу к ошибке копирования и вставки), я думаю, что ваша основная проблема заключается в отсутствии типа содержимого.
Предполагается, что функция getContentType()
угадывает тип содержимого по расширению имени файла. Однако там нечего обрабатывать файл .json. Таким образом, по умолчанию будет использоваться text/plain
, который не будет интерпретироваться как данные JSON.
Вам нужно немного добавить, чтобы искать файлы JSON и соответствующим образом установить тип содержимого:
...
} else if (filename.endsWith(".json")) {
return "application/json";
}
Я пробовал, но, к сожалению, это не то. В инструментах разработчика браузера запрашивается файл json, и запрос принимается, однако таблица остается пустой, даже если файл json отсутствует., @Mo'men Alaswad
Тогда что-то не так с кодом вашего сайта., @Majenko
попробуйте скопировать ответ и вручную проанализировать его с помощью JSON.parse()., @dandavis
- NodeMCU (Arduino IDE) «DynamicJsonBuffer» не был объявлен в этой области
- Чтение файла из SPIFFS в nodemcu с использованием ArduinoJson
- Последовательная связь от Arduino до ESP8266 NodeMCU работает, но от NodeMCU до Arduino не работает
- Проанализировать большой ответ json с помощью ESP8266
- Публиковать данные json в mqtt
- Какой максимальный размер статического документа Json в Arduino JSON?
- ESP8266 Arduino Json object array десериализация в структуру
- Как связать MPU9250 и NodeMcu?
Я думаю, что вы испортили свое копирование и вставку. Ваша функция loop(), кажется, находится в середине вашей функции setup()., @Majenko
Похоже, вы запускаете веб-страницу на своем ПК, но получаете json из ESP. Браузерам это не нравится, так как это своего рода межсайтовый скриптинг. Это может работать, если ESP также отправляет правильные заголовки разрешений. [Access-Control-Allow-Origin: *](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin), чтобы быть конкретным. Вы также можете открыть консоль разработчика в своем браузере, чтобы увидеть, появляются ли какие-либо ошибки. Также проверьте вкладку сети, чтобы узнать, запрашивается ли json., @Gerben
@Gerben Я не совсем уверен, что понимаю, что вы имеете в виду, моя веб-страница размещена на ESP, и я получаю к ней доступ через IP-адрес, однако в файле JS, связанном с моим HTML (кстати, оба хранятся в SPIFFS) я ищу файл json в той же папке, что и моя веб-страница, в этом проблема? И я проверил инструменты разработчика, да, файл json запрошен, и запрос имеет статус 200 OK., @Mo'men Alaswad
Неважно. Часть расширения VSCode меня сбила с толку, но, видимо, проблема не в этом., @Gerben