Express与EJS中res.render、res.send及SSR/CSR的新手疑问及实现可能性
关于Express渲染方式与SSR/CSR的清晰解答
嘿,作为新手有这些疑问太正常啦!咱先把这些概念和用法掰扯清楚:
首先纠正你的误解:res.render()和res.send()不直接对应SSR/CSR
这两个方法是Express里用来给客户端响应内容的工具,但它们的用途和对应的渲染模式不是严格绑定的:
- res.render():它的核心是调用你配置的模板引擎(比如EJS)在服务器端把模板文件和数据合并成完整的HTML页面,然后把这个渲染好的HTML发送给客户端。这种场景确实属于服务端渲染(SSR),因为页面的内容是服务器生成好的。
- res.send():它的灵活性很高,可以发送字符串、JSON对象、HTML片段甚至完整HTML。如果用它发送JSON数据,然后客户端通过JavaScript去请求数据并在浏览器里渲染页面,这属于客户端渲染(CSR);但如果用它直接发送一个完整的、已经写好的HTML页面,那其实也是SSR的一种实现方式。所以不能简单把res.send()等同于CSR。
搞懂SSR和CSR的核心区别
其实区分这两种渲染模式的关键是谁来生成完整的可显示页面:
- 服务端渲染(SSR):服务器接收请求后,把页面的所有内容(包括数据填充后的HTML)生成好,一次性发送给客户端。客户端拿到HTML就能直接显示,不需要再额外请求数据或者执行大量JS来渲染内容。
- 客户端渲染(CSR):服务器先发送一个“空架子”HTML(通常只有一个根DOM节点),客户端加载完基础JS后,再由JS主动向服务器请求数据,最后在浏览器里把数据和页面结构合并,生成可显示的内容。
当然可以用Express+EJS同时实现两种渲染方式
这俩组合完全能兼顾两种模式,给你举个实际的例子:
1. 实现SSR(用res.render()+EJS)
首先配置Express使用EJS模板引擎,然后写路由和模板:
// Express配置 const express = require('express'); const app = express(); app.set('view engine', 'ejs'); // 设置模板引擎为EJS app.set('views', './views'); // 指定模板文件存放目录 // SSR路由 app.get('/profile', (req, res) => { // 模拟从数据库获取用户数据 const userData = { name: 'Jacek Majer', age: 28, hobbies: ['coding', 'hiking', 'reading'] }; // 服务器端用EJS模板渲染完整HTML res.render('profile', userData); });
对应的EJS模板(./views/profile.ejs):
<!DOCTYPE html> <html> <head> <title>我的个人主页</title> </head> <body> <h1>欢迎来到<%= name %>的主页</h1> <p>年龄:<%= age %></p> <h3>我的爱好:</h3> <ul> <% hobbies.forEach(hobby => { %> <li><%= hobby %></li> <% }) %> </ul> </body> </html>
当用户访问/profile时,服务器会把模板和数据合并成完整的HTML发送给客户端,客户端直接显示,这就是标准的SSR。
2. 实现CSR(用Express提供API+EJS生成基础页面)
我们可以用Express做API服务器返回数据,同时用EJS生成客户端渲染的基础页面:
// 提供数据的API路由(CSR用) app.get('/api/hobbies', (req, res) => { const hobbies = ['coding', 'hiking', 'reading', 'photography']; res.send(hobbies); // 发送JSON数据给客户端 }); // CSR入口页面路由,用EJS生成基础HTML app.get('/csr-hobbies', (req, res) => { res.render('csr-hobbies'); });
对应的EJS模板(./views/csr-hobbies.ejs):
<!DOCTYPE html> <html> <head> <title>我的爱好(CSR版)</title> </head> <body> <div id="hobby-container"></div> <script> // 客户端JS:请求API数据并渲染页面 fetch('/api/hobbies') .then(response => response.json()) .then(hobbies => { const container = document.getElementById('hobby-container'); let html = '<h1>我的爱好</h1><ul>'; hobbies.forEach(hobby => { html += `<li>${hobby}</li>`; }); html += '</ul>'; container.innerHTML = html; }); </script> </body> </html>
这里客户端拿到的是只有一个空容器的HTML,然后通过JS请求API数据,在浏览器里生成页面内容,这就是CSR。你也可以把客户端的JS逻辑放到单独的.js文件里,用EJS引入,这样代码更整洁。
内容的提问来源于stack exchange,提问作者Jacek Majer
相关产品推荐
相关产品推荐

