如何用Node.js、Axios、EJS实现无刷新定时更新页面数据
无需刷新页面自动更新EJS模板中的API数据
问题分析
你当前的实现依赖服务器端渲染EJS模板,但页面加载完成后,客户端页面与服务器端的currentJoke变量不再关联。服务器定时更新currentJoke无法自动同步到已加载的页面,因此需要通过客户端JavaScript定时请求最新数据并更新DOM实现自动刷新。
解决方案
1. 后端新增API接口,提供最新笑话数据
修改Express代码,添加接口返回当前存储的笑话,并调整定时更新频率为10秒:
import express from "express"; import axios from "axios"; const app = express(); const port = 3000; let currentJoke = {}; // 存储当前笑话 const fetchJoke = async () => { try { const response = await axios.get("https://v2.jokeapi.dev/joke/any?type=twopart"); currentJoke = response.data; console.log(currentJoke); } catch (error) { console.error("获取笑话失败:", error.message); } }; // 10秒更新一次笑话(匹配需求) setInterval(fetchJoke, 10000); // 初始化获取第一个笑话 fetchJoke(); // 首页渲染时传入初始笑话 app.get("/",(req,res)=>{ res.render("index.ejs", { Service: currentJoke }); }); // 新增API接口,返回最新笑话 app.get("/api/joke", (req, res) => { res.json(currentJoke); }); app.listen(port,()=>{ console.log(`服务器运行在端口 ${port}`); });
2. 前端添加客户端JS,定时更新页面DOM
修改index.ejs,加入客户端脚本定时请求API并更新页面内容:
<!DOCTYPE html> <html> <head> <meta charset='utf-8'> <meta http-equiv='X-UA-Compatible' content='IE=edge'> <title>随机笑话</title> <meta name='viewport' content='width=device-width, initial-scale=1'> </head> <body> <div id="joke-container"> <% if(locals.Service && Service.setup) {%> <h1><%= Service.setup %></h1> <p><%= Service.delivery %></p> <% } else { %> <h1>加载中...</h1> <% } %> </div> <script> const jokeContainer = document.getElementById('joke-container'); // 更新笑话的函数 async function updateJoke() { try { const response = await fetch('/api/joke'); const joke = await response.json(); if (joke.setup && joke.delivery) { jokeContainer.innerHTML = ` <h1>${joke.setup}</h1> <p>${joke.delivery}</p> `; } } catch (error) { console.error('更新笑话失败:', error); } } // 每10秒执行一次更新 setInterval(updateJoke, 10000); </script> </body> </html>
核心逻辑说明
- 后端
/api/joke接口负责提供最新笑话数据,客户端通过fetch请求获取。 - 客户端JS使用
setInterval定时触发更新逻辑,获取新数据后直接修改页面DOM,无需刷新整个页面。 - 初始渲染时服务器传入第一个笑话,避免页面加载时显示空白。
- 服务器与客户端的定时频率保持一致(10秒),确保数据同步。
内容的提问来源于stack exchange,提问作者Bala
相关产品推荐
相关产品推荐

