我有一個頁面可以從 api 取得 100 個迷因。它在表格中顯示模因,每個模因都有一個詳細資訊按鈕,可將使用者帶到模因的詳細資訊頁面。我必須對 meme 路由執行 POST 請求並呈現 meme 詳細資料頁面。 post 請求成功,但 meme 頁面未從 router.post 中的 render() 渲染。
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.egs 按鈕:
<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 { // Make a POST request to the meme route with the meme and user data const response = await fetch("/meme", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ meme, user }), }); // Handle the response status if (!response.ok) { throw new Error("Network response was not ok"); } } catch (error) { // Handle any errors console.error(error); } }
終端機中的回應是:POST /meme 200 10.677 ms - 2703,但頁面上沒有任何呈現。
P粉7187309562023-09-09 16:21:06
首先我想提一下「但頁面上沒有任何內容呈現」。
它永遠不會自動渲染頁面,因為它在 MDN Webdocs 指出 fetch()
用於使用 AJAX 呼叫從網路取得資源。您取得的資源將儲存在response
變數中,您需要手動處理取得的資料(無論是操作DOM insideText 或重新導向至另一個頁面,例如使用window.href.location< /代码>)
但是,POST 請求通常用於在伺服器上建立/修改資料(請閱讀HTTP方法)。我看到您使用 POST 請求來渲染頁面/導航到另一個頁面。 GET 是 HTTP 方法,用於從伺服器請求資料。
我認為您最好更改處理handleDetailsClick
的方式。您可以使用 或簡單地修改
onclick
行為,使其具有
window.location.href=".../meme?id= "<%= meme.id %>
res.render() 渲染頁面就像下面的例子。
app.get("/meme", function (req, res) { const memeID = req.query.id; // Fetch the meme details from DB or any other data sources using the specified ID const memeDetails = db.findById(memeID); res.render("pages/meme", { memeDetails }); });
已更新
正如您所提到的分配要求,您可以稍微修改一下上面的POST 路由代碼(您可以只使用ID 或整個數據,具體取決於分配要求),而不是使用res.render () 要渲染html 頁面,您只需使用
res.JSON() 並利用
使用JS 的JSON 回應。
app.post("/meme", function (req, res) { const memeID = req.body.id; // Fetch the meme details from DB or any other data sources using the specified ID const memeDetails = db.findById(memeID); res.json({ success: true, data: { id : memeDetails.id, name: memeDetails.name, url : memeDetails.url, } }) });
<table> <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(<%= meme.id %>)">Details</button> </td> <% } %> </tr> <% }) %> </tbody> </table> <div id="selectedMeme"></div>
async function handleDetailsClick(id) { try { // Make a POST request to the meme route with the meme id const response = await fetch("/meme", { method: "POST", headers: { "Content-Type": "application/json", }, body: { id }, }); // Handle the response status if (!response.ok) { throw new Error("Network response was not ok"); } // Handle the response (convert to JSON and utilize it) const jsonResp = await response.json(); if (!jsonResp.success) { throw new Error("Something is error"); } // put the fetched data to HTML const memeData = jsonResp.data; document.getElementById('selectedMeme').innerHTML = ` <b>Meme name: ${memeData.name}</b> <br />Meme url: <a href="${memeData.url}">Click me</a> `; } catch (error) { // Handle any errors console.error(error); document.getElementById('selectedMeme').innerHTML = ''; } }