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
相关产品推荐
相关产品推荐

