ESP32向Apache服务器发送JSON字符串无法被前端JS接收问题
问题:ESP32 POST JSON到Apache服务器后,前端JS无法接收数据
ESP32-WROOM-32作为Web客户端,向Windows 11系统中Apache搭建的Web服务器发起POST请求,计划用前端JavaScript处理接收的JSON字符串。目前ESP32的VS Code终端显示请求状态码200,提示数据发送成功,但前端无法看到或接收ESP32发送的JSON字符串。
已完成的操作
1. Apache反向代理配置
启用mod_proxy模块并配置反向代理:
ProxyPass /post http://192.168.0.101:8000/ LoadModule proxy_module modules/mod_proxy.so LoadModule proxy_http_module modules/mod_proxy_http.so
2. 前端JS与HTML代码
JavaScript代码(serverJS.js)
const intervalID = setInterval(get_user_ID,1000); function get_user_ID() { var xhr = new XMLHttpRequest(); var requestURL = "/post"; xhr.open('POST', requestURL); xhr.send(); if (xhr.readyState == 4 && xhr.status == 200) { var response = JSON.parse(xhr.responseText); console.log(response); document.getElementById("esp_response").innerHTML = response.User; } }
HTML代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"/> <script async src='serverJS.js'></script> </head> <body> <h1>ESP32 get data</h1> <label id="esp_response_label">ESP32 response: </label> <div id="esp_response"></div> </body> </html>
运行结果:HTML标签正常显示,但浏览器控制台无数据,尝试fetch API也未成功,曾出现response=null的情况。
3. ESP32的esp_http_client代码片段
#define HTTP_ENDPOINT "192.168.0.101" static void http_rest_with_url(void) { esp_http_client_config_t config = { .host = HTTP_ENDPOINT, .path = "/", .query = "esp", .event_handler = _http_event_handler, .user_data = local_response_buffer, .disable_auto_redirect = true, }; esp_http_client_handle_t client = esp_http_client_init(&config); // POST const char *post_data = "{\"User\":\"User1-1919\"}"; esp_http_client_set_url(client, "http://"HTTP_ENDPOINT"/post"); esp_http_client_set_method(client, HTTP_METHOD_POST); esp_http_client_set_header(client, "Content-Type", "application/json"); esp_http_client_set_post_field(client, post_data, strlen(post_data)); err = esp_http_client_perform(client); if (err == ESP_OK) { ESP_LOGI(TAG, "HTTP POST Status = %d, content_length = %"PRId64, esp_http_client_get_status_code(client), esp_http_client_get_content_length(client)); } else { ESP_LOGE(TAG, "HTTP POST request failed: %s", esp_err_to_name(err)); } esp_http_client_cleanup(client); }
问题排查与解决方案
核心错误分析
- 架构逻辑混淆:ESP32的POST请求与前端JS的请求是两个独立的请求,没有数据传递关系。ESP32把数据发给Apache代理后的后端服务,但前端JS只是向同一路径发空POST请求,后端没有存储ESP32的数据并返回给前端,自然拿不到内容。
- Apache配置顺序错误:
LoadModule指令必须放在ProxyPass之前,否则模块未加载就配置代理,会导致代理不生效。 - 前端JS异步逻辑错误:XHR是异步操作,你直接同步判断
readyState ==4时,请求还未完成,无法获取响应。
修正步骤
1. 修复Apache代理配置顺序
调整指令顺序,确保先加载模块再配置代理:
LoadModule proxy_module modules/mod_proxy.so LoadModule proxy_http_module modules/mod_proxy_http.so ProxyPass /post http://192.168.0.101:8000/
2. 搭建后端存储服务
你需要一个运行在8000端口的后端服务(示例用Node.js),负责接收ESP32的POST数据并存储,同时向前端返回存储的数据:
// server.js const http = require('http'); let espData = {}; const server = http.createServer((req, res) => { res.setHeader('Access-Control-Allow-Origin', '*'); res.setHeader('Content-Type', 'application/json'); if (req.method === 'POST') { // 接收ESP32的POST数据 let body = ''; req.on('data', chunk => body += chunk.toString()); req.on('end', () => { try { espData = JSON.parse(body); res.writeHead(200); res.end(JSON.stringify({status: 'success'})); } catch (e) { res.writeHead(400); res.end(JSON.stringify({error: 'invalid JSON'})); } }); } else if (req.method === 'GET') { // 返回存储的ESP32数据给前端 res.writeHead(200); res.end(JSON.stringify(espData)); } }); server.listen(8000, '192.168.0.101', () => { console.log('服务运行在http://192.168.0.101:8000'); });
运行服务:node server.js
3. 修正前端JS逻辑
改为GET请求获取数据,并使用异步回调处理响应:
const intervalID = setInterval(get_esp_data, 1000); function get_esp_data() { var xhr = new XMLHttpRequest(); var requestURL = "/post"; xhr.open('GET', requestURL); xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { try { var response = JSON.parse(xhr.responseText); console.log(response); document.getElementById("esp_response").innerHTML = response.User; } catch (e) { console.error("解析JSON失败:", e); console.log("响应内容:", xhr.responseText); } } }; xhr.send(); }
4. 验证链路连通性
- 确保ESP32与Windows机器在同一局域网,IP地址正确
- 关闭Windows防火墙或允许Apache、8000端口的流量
- 用Postman手动测试:先POST JSON到
http://192.168.0.101/post,再GET该路径看是否返回数据,排除ESP32和前端的问题
内容的提问来源于stack exchange,提问作者Benedito Kolamy
相关产品推荐
相关产品推荐

