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

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);
}

问题排查与解决方案

核心错误分析

  1. 架构逻辑混淆:ESP32的POST请求与前端JS的请求是两个独立的请求,没有数据传递关系。ESP32把数据发给Apache代理后的后端服务,但前端JS只是向同一路径发空POST请求,后端没有存储ESP32的数据并返回给前端,自然拿不到内容。
  2. Apache配置顺序错误:LoadModule指令必须放在ProxyPass之前,否则模块未加载就配置代理,会导致代理不生效。
  3. 前端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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 21:42:08