ESP32 CAM同时使用esp_http_server与WebServer库出现间歇性404错误求助
解决方案:ESP32 WebServer与esp_http_server冲突导致的间歇性404错误
问题核心
Arduino标准WebServer库与ESP-IDF原生esp_http_server(startCameraServer()依赖该库)默认都监听TCP 80端口,两者的请求处理逻辑会互相抢占,导致部分请求被其中一方拦截后无法匹配对应路由,最终返回404错误。
方案1:统一使用esp_http_server实现所有功能(推荐)
放弃Arduino的WebServer,基于esp_http_server搭建完整服务,同时保留摄像头流功能:
- 保留
startCameraServer()调用,它会自动注册摄像头流相关路由(如/stream)。 - 手动为
esp_http_server添加自定义路由,处理LED PWM、RSSI查询及双向通信接口:// 自定义请求处理函数示例:返回RSSI值 esp_err_t get_rssi_handler(httpd_req_t *req) { int rssi = WiFi.RSSI(); char response[32]; snprintf(response, sizeof(response), "{\"rssi\": %d}", rssi); httpd_resp_send(req, response, HTTPD_RESP_USE_STRLEN); return ESP_OK; } // 在启动服务器后注册路由 void setup() { // 初始化WiFi、摄像头... httpd_handle_t camera_server = startCameraServer(); // 注册RSSI查询路由 httpd_uri_t rssi_uri = { .uri = "/api/rssi", .method = HTTP_GET, .handler = get_rssi_handler, .user_ctx = NULL }; httpd_register_uri_handler(camera_server, &rssi_uri); // 同理注册LED PWM控制等其他路由 }
方案2:改用Arduino生态摄像头库,统一使用WebServer
使用支持WebServer的Arduino摄像头封装库替代startCameraServer(),避免引入esp_http_server:
- 移除
startCameraServer()调用,在WebServer中注册摄像头流路由:#include "esp_camera.h" WebServer server(80); void handleStream() { server.setContentLength(CONTENT_LENGTH_UNKNOWN); server.send(200, "multipart/x-mixed-replace; boundary=frame"); while (true) { camera_fb_t *fb = esp_camera_fb_get(); if (!fb) continue; server.sendContent("--frame\r\n"); server.sendContent("Content-Type: image/jpeg\r\n\r\n"); server.sendContent((const char *)fb->buf, fb->len); server.sendContent("\r\n"); esp_camera_fb_return(fb); if (!server.client().connected()) break; } } void setup() { // 初始化WiFi、摄像头... server.on("/stream", handleStream); server.on("/api/rssi", [](){ int rssi = WiFi.RSSI(); server.send(200, "application/json", "{\"rssi\": " + String(rssi) + "}"); }); // 注册其他LED PWM控制路由... server.begin(); }
方案3:让两个服务器监听不同端口(不推荐)
如果必须同时使用两个库,修改其中一个服务器的监听端口:
- 例如将Arduino
WebServer改为监听8080端口:WebServer server(8080); - 网页端需对应调整请求地址:摄像头流访问
http://<esp32-ip>/stream,Ajax请求访问http://<esp32-ip>:8080/api/rssi - 注意:双服务器会占用更多ESP32资源,且增加代码维护复杂度,仅作为临时 workaround。
调试建议
- 开启ESP32串口日志(设置
Serial.begin(115200)),查看两个服务器的请求处理日志,确认请求被哪个模块拦截。 - 检查路由定义,避免两个服务器注册相同路径的路由。
内容的提问来源于stack exchange,提问作者Ray25
相关产品推荐
相关产品推荐

