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

Ubuntu+Firefox下ESP32嵌入式网页文件选择框打开缓慢问题

ESP32文件上传页面在Ubuntu Firefox中文件对话框卡顿问题

问题描述

我在ESP32 Arduino应用中实现了一个简单的文件上传功能,前端代码如下:

function uploadFile() {
  let file = document.getElementById("file1").files[0];
  let formdata = new FormData();
  formdata.append("file1", file);
  let ajax = new XMLHttpRequest();
  ajax.addEventListener("error", errorHandler, false);
  ajax.addEventListener("abort", abortHandler, false);
  ajax.open("POST", "/");
  ajax.send(formdata);
}

function errorHandler(event) {}

function abortHandler(event) {}
<form method="POST" action="/" enctype="multipart/form-data">
  <input type="file" name="file1" id="file1" onchange="uploadFile()"><br>
</form>

ESP32侧嵌入式Web服务器代码采用标准实现:

#include <AsyncTCP.h>
#include <SPIFFS.h>
#include <ESPmDNS.h>
#include <ESPAsyncWebServer.h>

// ...

AsyncWebServer _server;

MDNS.begin("my app");
MDNS.addService("http", "tcp", 80);

_server.onFileUpload(handleUpload);

_server.serveStatic("/", LittleFS, "/www")
    .setDefaultFile("index.html")
    .setTemplateProcessor(std::bind(&WebApp::processor, this, std::placeholders::_1));

_server.onNotFound([](AsyncWebServerRequest *request)
{ 
    request->send(404); 
});

_server.begin();

// ...

void handleUpload(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final) 
{
  if (!index) 
  {
    request->_tempFile = LittleFS.open("/" + filename, "w");
  }
  
  if (len) 
  {
    request->_tempFile.write(data, len);
  }

  if (final) 
  {
    request->_tempFile.close();
    request->redirect("/");
  }
}

在Ubuntu 23.04系统的Firefox浏览器中点击文件选择框时,打开文件对话框需10秒以上,切换目录也需数秒。但Android端Firefox或Ubuntu端Chrome无此问题。已排除固件代码问题,且代码在其他环境运行正常,询问是否可通过优化HTML页面解决该异常?


回答

可以通过以下HTML/JS优化解决该问题:

  • 分离表单与AJAX逻辑,消除默认行为干扰
    当前代码中<form>标签的默认POST提交逻辑可能导致Firefox在后台执行预提交检查,阻塞文件对话框的UI渲染。解决方案:

    • 直接移除<form>标签,改用普通<div>容器(AJAX上传无需依赖表单默认行为):
      <div>
        <input type="file" name="file1" id="file1" onchange="uploadFile()"><br>
      </div>
      
    • 若需保留表单,添加onsubmit="return false"阻止默认提交:
      <form method="POST" action="/" enctype="multipart/form-data" onsubmit="return false">
        <input type="file" name="file1" id="file1" onchange="uploadFile()"><br>
      </form>
      
  • 异步化AJAX操作,避免阻塞UI线程
    Firefox在触发文件选择框时,UI线程可能被同步执行的AJAX初始化逻辑占用,导致对话框加载延迟。将AJAX操作放入异步队列:

    function uploadFile() {
      setTimeout(() => {
        const file = document.getElementById("file1").files[0];
        if (!file) return;
        const formdata = new FormData();
        formdata.append("file1", file);
        const ajax = new XMLHttpRequest();
        ajax.addEventListener("error", errorHandler, false);
        ajax.addEventListener("abort", abortHandler, false);
        ajax.open("POST", "/");
        ajax.send(formdata);
      }, 0);
    }
    
  • 添加文件类型限制(可选)
    给文件输入框添加accept属性,缩小Firefox扫描文件系统的范围,加快对话框加载:

    <input type="file" name="file1" id="file1" onchange="uploadFile()" accept=".txt,.bin,.json"><br>
    
  • 禁用表单自动填充
    在页面头部添加meta标签,阻止Firefox对表单元素的预加载与自动填充逻辑:

    <meta name="autocomplete" content="off">
    

上述优化中,分离表单与AJAX逻辑的方案对这类Firefox特定卡顿问题改善最为显著,建议优先测试。


内容的提问来源于stack exchange,提问作者Mark

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 13:04:57