如何在ExpressJS中获取EJS页面HTML字符串并由控制器返回
如何用EJS生成HTML字符串并作为Express响应返回
完全理解你的需求——硬编码HTML字符串确实既不优雅也难维护,用EJS模板来生成HTML字符串才是正确的做法。下面一步步教你实现:
1. 准备工作:确保依赖和配置到位
首先,确认你的项目已经安装了ejs和express,如果没有的话先执行安装命令:
npm install express ejs
然后在你的Express应用中配置EJS作为模板引擎:
const express = require('express'); const app = express(); const ejs = require('ejs'); const fs = require('fs'); const path = require('path'); // 用来处理绝对路径,避免路径错误 // 设置EJS为模板引擎 app.set('view engine', 'ejs'); // 如果你的模板文件不在默认的`views`文件夹,手动指定路径: // app.set('views', path.join(__dirname, 'your-template-directory'));
2. 创建EJS模板文件
把HTML结构写到单独的EJS模板里,比如在views/employee.ejs中编写页面结构:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Employee Details</title> </head> <body> <h2>Employee Profile</h2> <div class="employee-card"> <p><strong>Name:</strong> <%= employee.name %></p> <p><strong>Position:</strong> <%= employee.position %></p> <p><strong>Department:</strong> <%= employee.department %></p> <p><strong>Email:</strong> <%= employee.email %></p> </div> </body> </html>
这里的<%= employee.name %>是EJS的插值语法,用来渲染你从JSON文件读取的数据。如果需要循环、条件判断等逻辑,也可以用EJS的对应语法实现。
3. 在路由中渲染模板为HTML字符串并返回
接下来修改你的路由控制器,读取JSON数据,用EJS渲染模板成字符串,最后返回这个字符串:
方式一:使用回调(传统写法)
router.get('/', function(req, res) { // 读取JSON文件的绝对路径(避免相对路径的坑) const jsonFilePath = path.join(__dirname, '../data/employeeDetails.json'); fs.readFile(jsonFilePath, 'utf8', (readErr, jsonData) => { if (readErr) { return res.status(500).send('Failed to load employee data'); } try { const employeeDetails = JSON.parse(jsonData); // 渲染EJS模板为HTML字符串 const templatePath = path.join(__dirname, '../views/employee.ejs'); ejs.renderFile(templatePath, { employee: employeeDetails }, (renderErr, htmlString) => { if (renderErr) { return res.status(500).send('Failed to render page'); } // 返回生成的HTML字符串 res.send(htmlString); }); } catch (parseErr) { res.status(500).send('Invalid employee data format'); } }); });
方式二:使用Async/Await(更简洁的异步写法)
如果你想避免回调地狱,可以用util.promisify把回调方法转成Promise,再用async/await写法:
const util = require('util'); // 把renderFile转成支持Promise的方法 const renderTemplate = util.promisify(ejs.renderFile); router.get('/', async function(req, res) { try { // 读取并解析JSON数据 const jsonFilePath = path.join(__dirname, '../data/employeeDetails.json'); const jsonData = await fs.promises.readFile(jsonFilePath, 'utf8'); const employeeDetails = JSON.parse(jsonData); // 渲染模板为HTML字符串 const templatePath = path.join(__dirname, '../views/employee.ejs'); const htmlString = await renderTemplate(templatePath, { employee: employeeDetails }); // 返回结果 res.send(htmlString); } catch (err) { res.status(500).send(`Error: ${err.message}`); } });
为什么这种方式更好?
- 把HTML结构和业务逻辑分离,代码更清晰易维护
- 模板文件可以单独修改样式和结构,不用改动控制器代码
- 利用EJS的模板语法(条件判断、循环等),可以轻松处理更复杂的页面渲染场景
内容的提问来源于stack exchange,提问作者deltaforce
相关产品推荐
相关产品推荐

