使用 SPIFFS 加载文件时出现问题 (ERR_CONTENT_LENGTH_MISMATCH)

2024-04-11

好吧,这两天我一直在研究这个问题,但我仍然觉得我一无所获。

我最近开始使用SPIFFS 文件系统 for Arduino开发于呼扎 ESP8266FSBrowser.ino例如,虽然它在分离代码方面非常出色,但随着我的代码不断增长,它在稳定性方面并不是很好。

自从我开始添加越来越多的 javascript 以来,我开始弹出各种文件的错误,无论是 HTML/CSS/JS,我看到的主要错误是ERR_CONTENT_LENGTH_MISMATCH.

//File Read for File System
bool handleFileRead(String path)
{
  if(mySerial)  
    mySerial.println("handleFileRead: " + path);
  if(path.endsWith("/")) path += "index.htm";
  String contentType = getContentType(path);
  String pathWithGz = path + ".gz";
  if(SPIFFS.exists(pathWithGz) || SPIFFS.exists(path))
  {


    if(SPIFFS.exists(pathWithGz))
      path += ".gz";
    File file = SPIFFS.open(path, "r");

    if(mySerial)
        mySerial.println("TEST: " + path + " FILE OPEN: " + file.size());

    size_t sent = server.streamFile(file, contentType);

    if(mySerial)
        mySerial.println("TEST: " + path + " SIZE: " + file.size());

    file.close();

    if(mySerial)
        mySerial.println("TEST: " + path + " FILE CLOSE");

    return true;
  } //end if 
  return false;
} //end function handleFileRead

因此,在那之后,我开始检查从 FSBrowser.h 示例复制的 handleFileRead() 函数,并在测试了各种打印语句后,似乎挂起发生在这一行中:

size_t 已发送 = server.streamFile(文件, contentType);

template<typename T> size_t streamFile(T &file, const String& contentType){
  setContentLength(file.size());
  if (String(file.name()).endsWith(".gz") &&
      contentType != "application/x-gzip" &&
      contentType != "application/octet-stream"){
    sendHeader("Content-Encoding", "gzip");
  }
  send(200, contentType, "");
  return _currentClient.write(file, HTTP_DOWNLOAD_UNIT_SIZE);
}

所以从那里,我进入了ESP8266WebServer.h并找到了流文件()功能。进入这个函数后,我发现了这一行:

返回 _currentClient.write(文件, HTTP_DOWNLOAD_UNIT_SIZE);

由此我推断出两件事:

  • HTTP_DOWNLOAD_UNIT_SIZE 有一个下载限制(定义为 1460)。
  • 该函数调用另一个函数WiFi客户端类称为write().

所以我跟踪了这​​个函数:size_t WiFiClient::write(const uint8_t *buf, size_t 大小)。

size_t WiFiClient::write(const uint8_t *buf, size_t size)
{

    SoftwareSerial mySerial(12,13); 

    mySerial.begin(115200);

    if(mySerial)
    {
        mySerial.print("Size: ");
        mySerial.println(size);
    }

    if (!_client || !size)
    {
        if(mySerial)
            mySerial.println("FAILURE");

        return 0;
    }

        if(mySerial)
            mySerial.println("SUCCESS");

    return _client->write(reinterpret_cast<const char*>(buf), size);
}

现在这不太匹配,因为调用的 write() 函数的第一个参数是类型File,虽然这个函数的第一个参数是 uint8_t,但我仍然在这里放置了一些打印语句,并且它们在加载文件时执行,所以我相信我已经找到了正确的函数。

但是,现在我不知道如何从这里继续解决问题,因为只有递归调用,并且错误似乎发生是因为罪魁祸首文件没有完成加载(至少根据 chrome 调试器的网络)标签)

如您所见,style.css 文件被列为3 KB,这当然是错误的:我的 css 文件是27 KB.

因此,似乎加载文件时出现问题(这不仅仅是 css 文件,我的 javascript 文件也发生了这种情况,并且似乎是随机的)。我已尝试缩小所有文件,但并没有解决问题;所以我确实需要一些帮助来确定如何解决这个问题。

现在我从另一个来源收到了一些建议来尝试使用这个库,它是FS浏览器 code: https://github.com/me-no-dev/ESPAsyncWebServer https://github.com/me-no-dev/ESPAsyncWebServer

起初这似乎解决了我所有的问题。代码运行稳定,没有出现以前的问题。但自从切换到该库以来,我遇到了无数新问题:

最奇怪的事情发生了,有些代码似乎丢失了?

如果您查看该照片中红色突出显示的行,您可以看到在removeClass()语句的中间,它停止拼写出类(即“deactiveSect”)并在下面开始一个完全不同的if语句代码。

然而,当前服务器上的代码相同部分如下:

您可以看到它似乎合并了第 66 行和第 70 行。

因此,虽然我使用的 FSBrowser 代码版本无法处理我正在使用的代码级别,但如果大量问题不断发生,我无法理解如何能够使用这个修改后的库。

这是我其余代码的源代码(带有原始的 FSBrowser 库):

主 ino 文件

//Header File
#include "HHIO_Portal.h"

//Function used to verify incoming information from the teensy to the wifi card via the communication protocol
void recInfoWifi()
{
    /*
    ===============================
    COMMUNICATION PROTOCOL - Removed due to post size limit
    ===============================
    */

} //end comProtocolWifi

//Function used to send information to the teensy in order to control the HHIO PTT
void sendInfoWifi()
{
    unsigned long currTime = millis();

    //SEND
    if(currTime - prevTimeTest > testInterval)   
    {
        prevTimeTest = currTime; 

        //Test Message
        messageLength = 3;
        subsys = SUBSYS_DBG;

        messageContent = wifiCounter; 

        //Teensy Console
        Serial.write(som);
        Serial.write(messageLength);
        Serial.write(subsys);
        Serial.write(messageContent);
        Serial.write(eom);

        wifiCounter++;

    } //end if (RECEIVE INFO)
} //end function sendInfoWifi

void setup()
{ 
  //Initiate Serial connection to Teensy
  Serial.begin(115200);

  //This is for debugging/housekeeping (And all console messages that use mySerial as opposed to Serial)
  mySerial.begin(115200);

  /*
  ===============================
  FILE SYSTEM
  ===============================
  */
  SPIFFS.begin();
  {
    Dir dir = SPIFFS.openDir("/");
    while (dir.next()) {    
      String fileName = dir.fileName();
      size_t fileSize = dir.fileSize();
      if(mySerial)
        mySerial.printf("FS File: %s, size: %s\n", fileName.c_str(), formatBytes(fileSize).c_str()); 
    } //end while
        if(mySerial)
            mySerial.printf("\n"); 
  } //end SPIFFS BEGIN  

  /*
  ===============================
  WIFI INIT
  ===============================
  */
  if(mySerial)
    mySerial.printf("Connecting to %s\n", ssid); 

  //Make the initial Wifi connection
  if (String(WiFi.SSID()) != String(ssid)) {
    WiFi.begin(ssid, password);
  } //end if

 //Wait for the Wifi to finish connecting
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    if(mySerial)
      mySerial.print("."); 
  } //end while

  //IP Address for webpage
  if(mySerial)
  {
      mySerial.println(""); 
      mySerial.print("Connected! IP address: "); 
      mySerial.println(WiFi.localIP()); 
  } //end if

  //Might not need this
  MDNS.begin(host);

  //Hostname for webpage
  if(mySerial)
  {
    mySerial.print("Open http://"); 
    mySerial.print(host); 
    mySerial.println(".local/edit to see the file browser"); 
  } //end if


  /*
  ===============================
  SERVER INIT
  ===============================
  */
  //list directory
  server.on("/list", HTTP_GET, handleFileList);
  //load editor
  server.on("/edit", HTTP_GET, [](){
    if(!handleFileRead("/edit.htm")) 
        server.send(404, "text/plain", "FileNotFound");
  });
  //create file
  server.on("/edit", HTTP_PUT, handleFileCreate);
  //delete file
  server.on("/edit", HTTP_DELETE, handleFileDelete);
  //first callback is called after the request has ended with all parsed arguments
  //second callback handles file uploads at that location
  server.on("/edit", HTTP_POST, [](){ server.send(200, "text/plain", ""); }, handleFileUpload);

  //called when the url is not defined here
  //use it to load content from SPIFFS
  server.onNotFound([](){
    if(!handleFileRead(server.uri()))
      server.send(404, "text/plain", "FileNotFound");
  });

  //get heap status, analog input value and all GPIO statuses in one json call
  server.on("/all", HTTP_GET, [](){
    String json = "{";
    json += "\"heap\":"+String(ESP.getFreeHeap());
    json += ", \"analog\":"+String(analogRead(A0));
    json += ", \"gpio\":"+String((uint32_t)(((GPI | GPO) & 0xFFFF) | ((GP16I & 0x01) << 16)));
    json += "}";
    server.send(200, "text/json", json);
    json = String();
  });

  //Start the server
  server.begin();

  if(mySerial)  
    mySerial.println("HTTP server started"); 

  //Open the websocket connection in order to update the status values on the page without refreshing
  webSocket.begin();
  webSocket.onEvent(webSocketEvent);
} //end Setup

void loop()
{   
    //SEND INFO TO TEENSY
    sendInfoWifi();

    //RECEIVE INFO FROM TEENSY
    recInfoWifi();

    //CONTINUE WEBSOCKET CONNECTION
    webSocket.loop();

    //SERVE WEBPAGE TO THE USER
    server.handleClient();
} //end loop

主ino头文件

//Initiate necessary libraries
#include <SoftwareSerial.h>
#include <HHIO_Subsystems.h>
#include <ESP8266WiFi.h>
//#include <pfodESP8266WiFi.h>
#include <WebSocketsServer.h>
//#include <pfodESP8266WebServer.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <FS.h>

//Serial connection for debugging (RX, TX)
SoftwareSerial mySerial(12,13); 

//SSID/Pass/Host
const char* ssid = "*****";
const char* password = "*****";
const char* host = "esp8266fs";

//Setup File System Connection
MDNSResponder mdns;

//Web Server
ESP8266WebServer server(80);

//File System 
File fsUploadFile;

//Websocket
WebSocketsServer webSocket = WebSocketsServer(81);

//Invalid Message
uint8_t invalidMessageFlag = 0;

//Counter for testing serial connection
uint8_t wifiCounter = 0;

//Com. Protocol Buffer
uint8_t rxBuff[256];

//Start of Message
uint8_t som = 0x11;

//End of Message
uint8_t eom = 0x12;

//Subsystem variables
uint8_t subsys; 
uint8_t receivedSubsys;

//Read Byte for Com. Protocol
uint8_t rx_byte = 0x00;

//Message length variables
uint8_t messageLength = 0;
uint8_t receivedMessageLength = 0;

//Message content variable
uint8_t messageContent;

//Variable to check incoming serial content
uint8_t serialCurrent; 

//Counter used for verifying the som variable
int initialCounter = 0;

//Message progression variables
boolean messageBegun = false; 
boolean messageInProgress = false;

//Variables currently used to read status info coming from the teensy (CURRENTLY RANDOMIZED INFO)
int currNumRefresh = 0;
int currMicroC = 0;
int currMicroD = 0;
int currMicroE = 0;
int currPressureC = 0; 
int currPressureD = 0; 
int currPressureE = 0; 
int currValveStatusNumC = 0; 
int currValveStatusNumD = 0; 
int currValveStatusNumE = 0;
int currFluid = 0;

//Buffer for sending information from Arduino to the webpage
char statusbuf[256]; 

//Valve 1
String valveStatusC = "Closed";
String valveTubePropsC = "175px solid #00ADEF";
String valveColorC = "red";

//Valve 2
String valveStatusD = "Closed";
String valveTubePropsD = "175px solid #00ADEF";
String valveColorD = "red";

//Valve 3
String valveStatusE = "Closed";
String valveTubePropsE = "175px solid #00ADEF";
String valveColorE = "red";

//Variables for sending test message to teensy
long prevTimeTest = 0;
long testInterval = 5000;

//Format Bytes
String formatBytes(size_t bytes){

  if(mySerial)  
    mySerial.println("formatBytes FUNC");

  if (bytes < 1024){
    return String(bytes)+"B";
  } //end if 

  else if(bytes < (1024 * 1024)){
    return String(bytes/1024.0)+"KB";
  } //end else if

  else if(bytes < (1024 * 1024 * 1024)){
    return String(bytes/1024.0/1024.0)+"MB";
  } //end else if
  else {
    return String(bytes/1024.0/1024.0/1024.0)+"GB";
  } //end else
} //end function formatBytes

//Content Type for File System
String getContentType(String filename)
{
  if(server.hasArg("download")) return "application/octet-stream";
  else if(filename.endsWith(".htm")) return "text/html";
  else 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(".png")) return "image/png";
  else if(filename.endsWith(".gif")) return "image/gif";
  else if(filename.endsWith(".jpg")) return "image/jpeg";
  else if(filename.endsWith(".ico")) return "image/x-icon";
  else if(filename.endsWith(".xml")) return "text/xml";
  else if(filename.endsWith(".pdf")) return "application/x-pdf";
  else if(filename.endsWith(".zip")) return "application/x-zip";
  else if(filename.endsWith(".gz")) return "application/x-gzip";

  if(mySerial)  
    mySerial.println("getContentType FUNC");

  return "text/plain";
} //end function getContentType

//File Read for File System
bool handleFileRead(String path)
{
  if(mySerial)  
    mySerial.println("handleFileRead: " + path);
  if(path.endsWith("/")) path += "index.htm";
  String contentType = getContentType(path);
  String pathWithGz = path + ".gz";
  if(SPIFFS.exists(pathWithGz) || SPIFFS.exists(path))
  {


    if(SPIFFS.exists(pathWithGz))
      path += ".gz";
    File file = SPIFFS.open(path, "r");

    if(mySerial)
        mySerial.println("TEST: " + path + " FILE OPEN: " + file.size());

    size_t sent = server.streamFile(file, contentType);

    if(mySerial)
        mySerial.println("TEST: " + path + " SIZE: " + file.size());

    file.close();

    if(mySerial)
        mySerial.println("TEST: " + path + " FILE CLOSE");

    return true;
  } //end if 
  return false;
} //end function handleFileRead

//File Upload for File System
void handleFileUpload(){
  if(server.uri() != "/edit") return;
  HTTPUpload& upload = server.upload();
  if(upload.status == UPLOAD_FILE_START)
  {
    String filename = upload.filename;
    if(!filename.startsWith("/")) 
        filename = "/"+filename;
    if(mySerial)
    {
        mySerial.print("handleFileUpload Name: "); 
        mySerial.println(filename);
    } //end if

    fsUploadFile = SPIFFS.open(filename, "w");
    filename = String();
  } //end if 
  else if(upload.status == UPLOAD_FILE_WRITE)
  {
    if(mySerial)
    {
        mySerial.print("handleFileUpload Data: "); 
        mySerial.println(upload.currentSize);
    } //end if

    if(fsUploadFile)
      fsUploadFile.write(upload.buf, upload.currentSize);
  } //end else if
  else if(upload.status == UPLOAD_FILE_END)
  {
    if(fsUploadFile)
      fsUploadFile.close();
    if(mySerial)
    {
        mySerial.print("handleFileUpload Size: "); 
        mySerial.println(upload.totalSize);
    } //end if
  } //end else if
} //end function handleFileUpload

//File Delete for File System
void handleFileDelete()
{
  if(server.args() == 0) return server.send(500, "text/plain", "BAD ARGS");
  String path = server.arg(0);
  if(mySerial)
    mySerial.println("handleFileDelete: " + path);
  if(path == "/")
    return server.send(500, "text/plain", "BAD PATH");
  if(!SPIFFS.exists(path))
    return server.send(404, "text/plain", "FileNotFound");
  SPIFFS.remove(path);
  server.send(200, "text/plain", "");
  path = String();
} //end function handleFileDelete

//File Create for File System
void handleFileCreate()
{
  if(server.args() == 0)
    return server.send(500, "text/plain", "BAD ARGS");
  String path = server.arg(0);
  if(mySerial)
      mySerial.println("handleFileCreate: " + path);
  if(path == "/")
    return server.send(500, "text/plain", "BAD PATH");
  if(SPIFFS.exists(path))
    return server.send(500, "text/plain", "FILE EXISTS");
  File file = SPIFFS.open(path, "w");
  if(file)
    file.close();
  else
    return server.send(500, "text/plain", "CREATE FAILED");
  server.send(200, "text/plain", "");
  path = String();
} //end function handleFileCreate

void handleFileList() 
{
  if(!server.hasArg("dir")) 
  {
      server.send(500, "text/plain", "BAD ARGS"); 
      return;
  } //end if

  String path = server.arg("dir");
  if(mySerial)
    mySerial.println("handleFileList: " + path);
  Dir dir = SPIFFS.openDir(path);
  path = String();

  String output = "[";
  while(dir.next())
  {
    File entry = dir.openFile("r");
    if (output != "[") output += ',';
    bool isDir = false;
    output += "{\"type\":\"";
    output += (isDir)?"dir":"file";
    output += "\",\"name\":\"";
    output += String(entry.name()).substring(1);
    output += "\"}";
    entry.close();
  } //end while

  output += "]";
  server.send(200, "text/json", output);
} //end function handleFileList

//HHIO PTT POWER LED ON
void switchPOWERon() {

    int powerStatusLength = 1;

    subsys = SUBSYS_1; 

    //Account for the end of message
    messageLength = powerStatusLength + 2;

    messageContent = 1;

    Serial.write(som);
    Serial.write(messageLength);
    Serial.write(subsys);
    Serial.write(messageContent);
    Serial.write(eom);
} //end switchPOWERon

//HHIO PTT POWER LED OFF
void switchPOWERoff() {

    int powerStatusLength = 1;

    subsys = SUBSYS_1; 

    //Account for the end of message
    messageLength = powerStatusLength + 2;

    messageContent = 0;

    Serial.write(som);
    Serial.write(messageLength);
    Serial.write(subsys);
    Serial.write(messageContent);
    Serial.write(eom);
} //end switchPOWERoff

//PUMP POWER ON
void pumpPOWERon() {

    int pumpPowerStatusLength = 1;

    subsys = SUBSYS_2; 

    //Account for the end of message
    messageLength = pumpPowerStatusLength + 2;

    messageContent = 1;

    Serial.write(som);
    Serial.write(messageLength);
    Serial.write(subsys);
    Serial.write(messageContent);
    Serial.write(eom);
} //end switchPOWERon

//PUMP POWER OFF
void pumpPOWERoff() {

    int pumpPowerStatusLength = 1;

    subsys = SUBSYS_2; 

    //Account for the end of message
    messageLength = pumpPowerStatusLength + 2;

    messageContent = 0;

    Serial.write(som);
    Serial.write(messageLength);
    Serial.write(subsys);
    Serial.write(messageContent);
    Serial.write(eom);
} //end switchPOWERoff

//LED POWER ON
void switchLEDon() {

    int ledStatusLength = 1;

    subsys = SUBSYS_3; 

    //Account for the end of message
    messageLength = ledStatusLength + 2;

    messageContent = 1;

    Serial.write(som);
    Serial.write(messageLength);
    Serial.write(subsys);
    Serial.write(messageContent);
    Serial.write(eom);
} //end switchLEDon

//LED POWER OFF
void switchLEDoff() {

    int ledStatusLength = 1;

    subsys = SUBSYS_3; 

    //Account for the end of message
    messageLength = ledStatusLength + 2;

    messageContent = 0;

    Serial.write(som);
    Serial.write(messageLength);
    Serial.write(subsys);
    Serial.write(messageContent);
    Serial.write(eom);
} //end switchLEDoff

//Function to send all updated status values from arduino to the webpage
void statusUpdate(uint8_t num) {

    //Valve C
    if(currValveStatusNumC == 0)
    {
        valveColorC = "red";
        valveTubePropsC = "175px solid #00ADEF";
        valveStatusC = "Closed";
    } //end if
    else if(currValveStatusNumC == 1)
    {
        valveColorC = "green";
        valveTubePropsC = "350px solid #00ADEF"; 
        valveStatusC = "Open";
    } //end else if

    //Valve D
    if(currValveStatusNumD == 0)
    {
        valveColorD = "red";
        valveTubePropsD = "175px solid #00ADEF";
        valveStatusD = "Closed";
    } //end if
    else if(currValveStatusNumD == 1)
    {
        valveColorD = "green";
        valveTubePropsD = "350px solid #00ADEF"; 
        valveStatusD = "Open";
    } //end else if

    //Valve E
    if(currValveStatusNumE == 0)
    {
        valveColorE = "red";
        valveTubePropsE = "175px solid #00ADEF";
        valveStatusE = "Closed";
    } //end if
    else if(currValveStatusNumE == 1)
    {
        valveColorE = "green";
        valveTubePropsE = "350px solid #00ADEF"; 
        valveStatusE = "Open";
    } //end else if

    String test = ""; 
    test += currNumRefresh;
    test += ",";
    test += currMicroC;
    test += ",";
    test += currMicroD;
    test += ",";
    test += currMicroE;
    test += ",";
    test += currPressureC;
    test += ","; 
    test += currPressureD;
    test += ",";
    test += currPressureE;
    test += ","; 
    test += valveColorC;
    test += ",";
    test += valveTubePropsC;
    test += ",";
    test += valveStatusC;
    test += ","; 
    test += valveColorD;
    test += ",";
    test += valveTubePropsD;
    test += ",";
    test += valveStatusD;
    test += ","; 
    test += valveColorE;
    test += ",";
    test += valveTubePropsE;
    test += ",";
    test += valveStatusE;
    test += ",";
    test += currFluid;

    test.toCharArray(statusbuf, 256);
    webSocket.sendTXT(num, statusbuf, strlen(statusbuf));
} //end function statusUpdate

// Current POWER status
bool POWERStatus;

// Current LED status
bool LEDStatus;

// Commands sent through Web Socket
const char LEDON[] = "ledon";
const char LEDOFF[] = "ledoff";

const char teensyPOWERON[] = "teensyPOWERon";
const char teensyPOWEROFF[] = "teensyPOWERoff";

const char pumpPOWERON[] = "pumpPOWERon";
const char pumpPOWEROFF[] = "pumpPOWERoff";

const char teensyLEDON[] = "teensyLEDon";
const char teensyLEDOFF[] = "teensyLEDoff";

const char statusIdentifier[] = "Update Status";


//Websocket Event Function
void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length)
{
  //if(mySerial)
   //mySerial.printf("webSocketEvent(%d, %d, ...)\r\n", num, type);
  switch(type) {
    case WStype_DISCONNECTED:
      //if(mySerial)
          //mySerial.printf("[%u] Disconnected!\r\n", num);
      break;
    case WStype_CONNECTED:
      {
        IPAddress ip = webSocket.remoteIP(num);
        //if(mySerial)
          //mySerial.printf("[%u] Connected from %d.%d.%d.%d url: %s\r\n", num, ip[0], ip[1], ip[2], ip[3], payload);

      } //end case CONNECTED
      break;
    case WStype_TEXT:
      //if(mySerial)
        //mySerial.printf("[%u] get Text: %s\r\n", num, payload);

      if(strcmp(teensyPOWERON,  (const char *)payload) == 0) {
          switchPOWERon();
      } //end if

      else if(strcmp(teensyPOWEROFF,  (const char *)payload) == 0) {
          switchPOWERoff();
      } //end else if

      else if(strcmp(pumpPOWERON,  (const char *)payload) == 0) {
          pumpPOWERon();
      } //end else if

      else if(strcmp(pumpPOWEROFF,  (const char *)payload) == 0) {
          pumpPOWERoff();
      } //end else if

      else if(strcmp(teensyLEDON,  (const char *)payload) == 0) {
          switchLEDon();
      } //end else if

      else if(strcmp(teensyLEDOFF,  (const char *)payload) == 0) {
          switchLEDoff();
      } //end else if

      else if(strcmp(statusIdentifier, (const char *)payload) == 0) {
          statusUpdate(num);
      } //end else if
      else 
      {
        if(mySerial)
            mySerial.println("Unknown command");
      } //end else

      // send data to all connected clients
      webSocket.broadcastTXT(payload, length);
      break;
    case WStype_BIN:
      if(mySerial)
        mySerial.printf("[%u] get binary length: %u\r\n", num, length);
      hexdump(payload, length);

      // echo data back to browser
      webSocket.sendBIN(num, payload, length);
      break;
    default:
      if(mySerial)
        mySerial.printf("Invalid WStype [%d]\r\n", type);
      break;
  } //end switch
} //end function webSocketEvent

我还包含了 jQuery 和这个仪表库:https://github.com/Mikhus/canv-gauge https://github.com/Mikhus/canv-gauge.

以下是当前 SPIFFS 服务器上的完整文件列表:

由于帖子大小限制,我没有包含 HTML/CSS/JS;如果这有帮助,请告诉我,我会在回复中发布该代码。


好吧,我似乎通过使用修改后的库、压缩代码并完全删除 jQuery 基本上解决了这个问题。我仍然偶尔会遇到错误,但这些似乎是不可避免的,并且大多数时候一切正常。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 SPIFFS 加载文件时出现问题 (ERR_CONTENT_LENGTH_MISMATCH) 的相关文章

  • 如何结合 websockets 和 http 来创建一个保持数据最新的 REST API? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我正在考虑使用 websockets 和 http 构建一个 REST API 其中我使用 websockets 告诉客户端新数据可用或直接向客
  • 如何使用我的 xampp 服务器以便外部网络中的每个人都可以访问它

    我现在已经遇到这个问题一个多星期了 我正在我的计算机上运行我的世界服务器 因此我使用 no ip org 来获得 固定 IP 我转发了服务器的所有端口 我的朋友可以毫无问题地访问 后来我想我可以做一些统计数据之类的小事 所以我安装了xamp
  • 如何使用GSM模块SIM800和Arduino Uno发送短信?

    我正在尝试通过 SIM800 GSM 模块从 Arduino 发送短信 消息到达给定号码 但格式不正确 它显示 消息格式不支持 我在这里添加了我的代码 非常感谢您的快速回复 include
  • Python 的 SignalR 替代方案

    Python 世界中 SignalR 的替代方案是什么 准确地说 我在Windows 8上使用tornado和python 2 7 6 我发现sockjs龙卷风 https github com MrJoes sockjs tornado
  • NodeJS Websocket如何在服务器重新启动时重新连接

    在 Node js 中我使用网络套接字 ws https github com websockets ws用于 WebSocket 连接 以下是客户端的代码 假设我们正在连接的服务器套接字宕机了一分钟 close 事件将会触发 但是每当服务
  • Websocket、Angular 2 和 JSON Web 令牌身份验证

    我的 Angular 2 应用程序 用打字稿编码 有一个简单的身份验证方案 用户登录 服务器返回 JSON Web 令牌 JWT abc123 在每次 API 调用时 应用程序都会将 JWT 发送到Authorization header
  • 在 Arduino 上将整数/小数转换为十六进制?

    如何将整数或小数变量转换为十六进制字符串 我可以做相反的事情 将十六进制转换为整数 但我无法找出其他方法 这是为了Serial print 数组中的十六进制值 查看 Arduino 字符串教程here http arduino cc en
  • 我可以在浏览器中启动 socket.io/websocket 服务器吗?

    之前有人问过这个问题 答案是否定的 但是现在 有了 browserify webpack 我可以像在服务器上那样编写代码吗 它会在浏览器中运行 还是有任何限制使这变得不可能 你不能 在浏览器中启动服务器需要访问浏览器中根本不存在的低级功能
  • 我可以使用单个 websocket 服务器同时打开 2 个端口吗

    我是 websocket 编程的新手 目前我正在开发一个简单的 websocket 服务器 使用 c 可以响应 websocket 客户端 我设法在单个端口上使用 1 个客户端和 1 个服务器 我想知道是否可以打开 2 个端口 以便不同的客
  • 如何使用 Scarlet 在 Android 上通过 WebSocket 进行连接?

    README md 中的代码 val scarletInstance Scarlet Builder webSocketFactory okHttpClient newWebSocketFactory GDAX URL addMessage
  • 简单游戏服务器的代码示例

    我想为游戏中心构建一款 iPhone 游戏 目前正在研究其中的服务器部分 我通过示例学习得最好 但我很难找到任何简单游戏服务器的示例来演示 数据如何格式化并发送到服务器以及如何接收 如何验证正在发送 接收的数据以避免玩家作弊等 游戏服务器代
  • websocket握手问题

    我正在使用 python 实现一个简单的 websocket 服务器 我使用的握手来自 握手本身似乎有效 但是当我点击发送时 我收到一个 JavaScript 错误 未捕获的错误 INVALID STATE ERR DOM 异常 11 这是
  • Tyrus WebSockets (Java) - 如何设置客户端本地 IP 地址

    使用 WebSockets Tyrus 时有没有办法指定本地 IP 地址和端口 我正在寻找你可以用完整的 4 个参数构造函数做的同样的事情Socket http docs oracle com javase 6 docs api java
  • 接收客户端返回的数据

    我使用套接字连接从服务器发送了一个缩放数组到客户端 它运行良好 现在我想将数据发送回服务器以在服务器中取消缩放 数据一次每行发送到客户端 因此我尝试将它们按顺序放回到名为 Final 的空数组中 这是服务器 py import socket
  • 如何从普通请求调用(即@RequestMapping)调用@SendTo

    我已经使用 Spring MVC 实现了 Web Socket 它对我来说工作得很好 即从一个浏览器工作到另一个浏览器 该浏览器对使用此代码的套接字开放 MessageMapping hello SendTo topic greetings
  • 客户端使用高端口号

    为什么客户端会结束连接 使用高端口号 临时端口 而应用程序 监听通常较小的端口号 谢谢你的优点 卡蒂克 巴拉古鲁 服务器侦听固定端口号 以便客户端知道连接到哪里 客户端不需要使用固定端口号 因为没有人发起与它们的连接 事实上 如果同一台计算
  • 生成唯一硬件 ID 的可靠方法

    问题 我必须为每个联网客户端提供唯一的 ID 例如 一旦客户端软件安装在目标计算机上 它 ID 应该持续存在 并且如果在同一台计算机和相同的操作系统安装上重新安装软件 它应该继续存在 如果以大多数方式修改硬件配置 除了更改主板 它不应该改变
  • Dart 将客户端 Socket 升级为 WebSocket

    Since WebSocket https api dartlang org stable 2 1 0 dart io WebSocket class html在 Dart 中不允许直接设置安全上下文 https api dartlang
  • 当我启动程序时,Arduino IDE (Win10) 崩溃

    我的 Arduino IDE Win10 上的版本为 1 8 12 在启动时崩溃 运行arduino debug exe我收到此错误消息 C Program Files x86 Arduino gt arduino debug exe Se
  • 玩 Scala Akka WebSockets 更改 actor 路径

    我遵循使用 Scala Play 和 Akka Actor 创建 Web 套接字的示例 https www playframework com documentation 2 5 x ScalaWebSockets Handling Web

随机推荐