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

单页应用禁用页面刷新时,能否使用EJS实现服务端渲染?

解决方案:SPA无刷新导航与EJS的取舍

一、如何规避手动输入地址/location.assign导致的页面刷新?

完全可以实现,核心是前端路由拦截配合服务端 fallback 配置,让所有导航行为都在SPA内部处理,不触发浏览器刷新:

1. 服务端调整路由

  • 将原页面路由改为API接口,返回动态HTML片段或数据,而非完整页面;
  • 添加一个 catch-all 路由,所有非API请求都返回SPA的主入口页面(包含WebGL逻辑和前端路由)。

示例代码:

// 原/test路由改为API,返回EJS渲染的HTML片段
server.get('/api/test', (req, res) => {
  // 渲染仅包含动态内容的EJS片段(比如test-fragment.ejs)
  res.render('test-fragment', { /* 传入渲染所需数据 */ }, (err, html) => {
    res.send(html);
  });
});

// Catch-all路由:所有非API请求返回SPA主页面
server.get('*', (req, res) => {
  res.render('index'); // index.ejs是SPA入口,包含WebGL和前端路由逻辑
});

2. 前端拦截导航行为

  • 拦截所有内部链接的点击事件,阻止默认跳转,用history.pushState更新URL;
  • 监听popstate事件,处理浏览器前进/后退;
  • 发起fetch请求获取动态内容,手动更新页面的指定容器,同时保留WebGL上下文。

示例代码:

// 拦截a标签点击,实现无刷新导航
document.addEventListener('click', (e) => {
  const link = e.target.closest('a');
  if (link && link.href.startsWith(window.location.origin)) {
    e.preventDefault();
    const path = new URL(link.href).pathname;
    // 更新URL而不刷新页面
    history.pushState({ path }, '', path);
    // 加载对应页面内容
    loadDynamicContent(path);
  }
});

// 处理浏览器前进/后退
window.addEventListener('popstate', (e) => {
  if (e.state?.path) {
    loadDynamicContent(e.state.path);
  }
});

// 加载并更新动态内容
async function loadDynamicContent(path) {
  // 请求对应API获取HTML片段
  const res = await fetch(`/api${path}`);
  const html = await res.text();
  // 更新页面中的动态内容容器
  document.getElementById('dynamic-container').innerHTML = html;
  // 同步更新WebGL场景(根据路由调整)
  updateWebGLScene(path);
}

这样处理后,无论是手动输入地址(服务端返回主页面,前端路由解析URL并加载内容),还是点击链接,都不会触发页面刷新,WebGL上下文始终保持活跃。

二、必须前端手动渲染时,是否需要放弃EJS?

不需要,可以根据需求选择两种方案:

1. 保留EJS做服务端片段渲染

继续用EJS在服务端渲染动态HTML片段(仅页面的可变部分,不含页面骨架),前端fetch后直接插入页面。这种方式可以利用EJS的模板语法在服务端处理数据,减少前端模板的开发量,适合数据逻辑更偏向服务端的场景。

2. 改用前端模板渲染

如果希望完全在前端做渲染,服务端只需返回JSON数据,前端使用模板字符串、Handlebars、Vue/React模板等方式渲染HTML。这种方式更符合前后端分离的SPA模式,适合交互复杂、需要前端控制渲染逻辑的场景。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 23:27:45