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

Express.js项目中客户端与服务端JS混写报错及数据交互问题

问题分析与解决方案

为什么会报错?

你把客户端浏览器专属的API(比如document)和Express服务端代码写在一起了。Node.js(运行Express的环境)根本没有document这个对象——document是浏览器用来操作DOM的工具,服务端跑的代码碰不到浏览器的DOM,所以直接报错document is not defined。

结论:绝对不能把客户端JS和服务端Express代码混写在同一个文件里,两者运行环境完全不同,必须拆分。

正确实现前后端交互的步骤

1. 拆分代码文件

把原来的代码分成三个独立部分:

  • 服务端逻辑:app.js(只处理Express路由、服务器启动)
  • 客户端逻辑:client.js(处理页面DOM操作、数据提交)
  • 页面结构:index.html(保持页面布局,修改JS引入路径)

2. 配置服务端(app.js)

添加中间件解析表单数据,确保静态文件可访问:

const express = require("express")
const app = express();
const path = require("path")

// 解析表单提交的url编码数据
app.use(express.urlencoded({ extended: true }))
// 托管静态文件(html、css、客户端js都放在当前目录)
app.use(express.static("./"))

app.listen(5000, () => {
    console.log("Server listening on port 5000...")
})

app.get("/", (req, res) => {
    res.sendFile(path.join(__dirname, "index.html"), (err) => {
        if(err) console.log(err)
    })
})

// 新增POST路由,接收客户端提交的邮箱
app.post("/submit-email", (req, res) => {
    const userEmail = req.body.email;
    console.log("收到邮箱:", userEmail);
    // 这里可以扩展逻辑,比如存数据库、发送确认邮件等
    res.send({ status: "success", message: `已收到邮箱:${userEmail}` })
})

3. 客户端逻辑(client.js)

专门处理页面交互和数据提交,放在静态目录下:

const enterEmail = document.getElementById("email")
const submitBtn = document.getElementById("submit")
const statusEl = document.getElementById("status")

submitBtn.addEventListener("click", async (e) => {
    e.preventDefault(); // 阻止默认表单提交,避免页面刷新
    const email = enterEmail.value.trim();
    if(!email) {
        statusEl.textContent = "请输入有效的邮箱地址";
        return;
    }

    try {
        // 用fetch把数据发给服务端的POST路由
        const response = await fetch("/submit-email", {
            method: "POST",
            headers: {
                "Content-Type": "application/x-www-form-urlencoded",
            },
            body: `email=${encodeURIComponent(email)}`
        });
        const result = await response.json();
        statusEl.textContent = result.message;
        enterEmail.value = ""; // 清空输入框
    } catch (err) {
        statusEl.textContent = "提交失败,请重试";
        console.error(err);
    }
})

4. 修改HTML文件

把原来的JS引入改成指向客户端的client.js,同时调整提交按钮类型:

<!DOCTYPE html>
<html>
    <head>
        <link rel="stylesheet" href="./styles.css">
    </head>
    <body>
        <input id="email" placeholder="enter email" type="text">
        <button id="submit">提交</button> <!-- 改成button类型,避免默认表单提交行为 -->
        <h1 id="status">Submitted email: </h1>

        <script src="./client.js"></script>
    </body>
</html>

运行说明

  1. 确保三个文件(app.js、client.js、index.html)在同一目录下
  2. 终端运行node app.js启动服务
  3. 浏览器访问http://localhost:5000,输入邮箱提交后,服务端控制台会打印收到的邮箱,页面也会显示提交状态

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 06:10:38