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

Express中POST路由无法渲染Meme详情页问题求助

问题描述

我开发了一个页面,从API获取100个meme并以表格形式展示,每个meme都配有详情按钮。点击按钮后需要通过POST请求到/meme路由,渲染meme详情页。目前POST请求已成功(终端显示POST /meme 200 10.677 ms - 2703),但router.post中的res.render()并未渲染出meme详情页。

相关代码

Meme.js(后端路由)

var express = require("express");
var router = express.Router();
var bodyParser = require("body-parser");
var jsonParser = bodyParser.json();
var ensureLogIn = require("connect-ensure-login").ensureLoggedIn;
var ensureLoggedIn = ensureLogIn();

router.post("/", ensureLoggedIn, jsonParser, (req, res, next) => {
  const meme = req.body.meme;
  const user = req.body.user;
  try {
    res.render("meme", { meme: meme, user: user });
  } catch (error) {
    console.error(error);
    res.status(500).send("Internal Server Error");
  }
});

module.exports = router;

memes.ejs(前端按钮部分)

<tbody>
  <% memes.forEach(meme=> { %>
    <tr class="meme-row <%= viewedMemeIds.includes(meme.id) ? 'viewed' : '' %>" data-meme-id="<%= meme.id %>">
      <td><img src="<%= meme.url %>" alt="<%= meme.name %>"></td>
      <td>
        <%= meme.name %>
      </td>
      <% if (user) { %>
        <td>
          <button class="btn-meme details-button" onclick="handleDetailsClick(<%= JSON.stringify(meme) %>, <%= JSON.stringify(user) %>)">Details</button>
        </td>
        <% } %>
    </tr>
    <% }) %>
</tbody>

MemeDetails.js(前端请求逻辑)

async function handleDetailsClick(meme, user) {
  try {
    const response = await fetch("/meme", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ meme, user }),
    });

    if (!response.ok) {
      throw new Error("Network response was not ok");
    }

  } catch (error) {
    console.error(error);
  }
}
问题原因

服务器端已经成功渲染出meme页面的HTML并返回,但前端的fetch请求仅发送了POST请求,并未处理服务器返回的HTML内容,因此页面不会自动更新展示详情页。

解决方法

方法一:修复POST请求的前端处理逻辑

修改MemeDetails.js,在请求成功后获取服务器返回的HTML并替换当前页面内容:

async function handleDetailsClick(meme, user) {
  try {
    const response = await fetch("/meme", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ meme, user }),
    });

    if (!response.ok) {
      throw new Error("Network response was not ok");
    }

    // 获取服务器返回的详情页HTML
    const detailHtml = await response.text();
    // 替换当前页面内容为详情页
    document.open();
    document.write(detailHtml);
    document.close();
  } catch (error) {
    console.error(error);
  }
}

方法二:改用GET请求(更符合REST规范)

POST请求多用于提交数据,获取详情页更适合用GET请求,让浏览器直接跳转渲染页面:

1. 修改后端路由(Meme.js)

var express = require("express");
var router = express.Router();
var ensureLogIn = require("connect-ensure-login").ensureLoggedIn;
var ensureLoggedIn = ensureLogIn();

// 改为GET路由,通过ID获取meme详情
router.get("/:id", ensureLoggedIn, async (req, res, next) => {
  try {
    const memeId = req.params.id;
    // 替换为你实际获取meme数据的逻辑(比如从数据库/API拉取)
    const meme = await fetchMemeById(memeId); 
    // 用户信息可通过ensureLoggedIn直接从req.user获取,无需前端传递
    const user = req.user;

    res.render("meme", { meme: meme, user: user });
  } catch (error) {
    console.error(error);
    res.status(500).send("Internal Server Error");
  }
});

module.exports = router;

2. 修改前端按钮(memes.ejs)

去掉fetch请求,直接跳转至GET路由:

<td>
  <button class="btn-meme details-button" onclick="window.location.href='/meme/<%= meme.id %>'">Details</button>
</td>

3. 删除MemeDetails.js

浏览器会自动发起GET请求并渲染新页面,无需再手动处理请求逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 18:07:08