如何不提交表单,通过Fetch从Express渲染EJS模板?
问题分析
你用Fetch请求只能拿到渲染后的HTML但页面不渲染,核心原因是Fetch属于AJAX异步请求——它只会帮你获取响应数据,不会自动触发浏览器的页面渲染流程;而表单提交是让浏览器直接发起页面跳转请求,浏览器会自动处理返回的HTML并渲染新页面。
两种解决方法
方法一:Fetch获取HTML后手动更新页面内容
修改前端login.js,在拿到响应的HTML后,手动替换当前页面的内容:
const form = document.getElementById('loginForm'); form.addEventListener('submit', async (e) => { e.preventDefault(); // 注意:URL要和后端路由匹配,后端是/index,所以这里要写完整地址 const response = await fetch('http://localhost:8000/index', { method: "get", // 获取HTML不需要设置Content-Type为json,改为声明接受text/html headers: { "Accept": "text/html", }, }); if (response.ok) { const html = await response.text(); // 替换整个页面内容,触发浏览器渲染 document.open(); document.write(html); document.close(); } });
后端app.js保持不变(注意路由/index要和前端请求的URL对应):
app.get('/index',(req,res)=>{ res.render('route.ejs'); })
方法二:直接跳转路由(更简洁)
如果不需要在请求前后做额外异步逻辑,完全可以不用Fetch,直接通过window.location.href跳转到目标路由,效果和表单提交一致但不会提交表单:
const form = document.getElementById('loginForm'); form.addEventListener('submit', (e) => { e.preventDefault(); // 直接跳转到后端渲染EJS的路由,浏览器自动处理渲染 window.location.href = 'http://localhost:8000/index'; });
这种方式浏览器会直接发起GET请求,Express返回渲染好的EJS页面,浏览器自动完成渲染,代码更简单。
额外注意点
- 前端请求的URL要和后端路由完全匹配,你之前代码里前端请求
localhost:8000/route,但后端路由是/index,这会导致404,必须修正一致。 - 用Fetch获取HTML时,不要设置
Content-Type: application/json,应该设置Accept: text/html告诉服务器你要HTML格式的响应。
内容的提问来源于stack exchange,提问作者RJ Ruhan
相关产品推荐
相关产品推荐

