如何将ExpressJS locals变量传入EJS模板并作为onload事件参数
问题解决:ExpressJS locals变量传入EJS模板onload事件参数错误
错误原因分析
- 异步执行顺序问题:全局中间件中数据库查询是异步操作,但
next()被放在异步回调之外,导致请求提前进入模板渲染阶段,此时app.locals.url还未完成赋值,模板中自然找不到url变量。 - EJS语法错误:模板中使用
<% url %>不会输出变量值(<% %>仅执行代码不输出),且未给字符串参数添加引号,不符合JavaScript语法要求。
修复步骤
1. 修正全局中间件的异步逻辑
将next()移到数据库查询的then回调内部,确保app.locals变量赋值完成后再继续处理请求;同时在catch中传递错误,避免请求挂起:
const hostname = "192.168.8.154"; const port = 3002; app.use('*', function (req, res, next) { db.collection('sys_params').find().toArray() .then(sysParams => { app.locals.sysParams = sysParams; app.locals.ipAddress = hostname; app.locals.portNo = port; app.locals.url = hostname + ':' + port; next(); // 确保locals赋值完成后再执行后续流程 }) .catch(error => { console.error(error); next(error); // 传递错误给错误处理中间件 }); });
2. 修正EJS模板的变量输出语法
使用<%= %>输出变量值,并给参数添加单引号,保证传递的是字符串类型:
<body onload="landingPage('<%= url %>')">
3. 优化前端JS函数(可选)
原函数中存在多余的引号嵌套问题,建议改用模板字符串拼接URL,并直接操作backgroundImage属性,避免覆盖其他样式:
<script type="text/javascript"> function landingPage(ipAddress){ // 随机加载登录页背景图 let loginDesktopArr = ["1-Sunday.jpg", "2-Monday.jpg", "3-Tuesday.jpg", "4-Wedsday.jpg", "5-Thursday.jpg", "6-Friday.jpg", "7-Saturday.jpg"]; let loginDesktopImg = loginDesktopArr[Math.floor(Math.random() * loginDesktopArr.length)]; let loginDesktopUrl = `http://${ipAddress}/img/${loginDesktopImg}`; document.getElementById('header').style.backgroundImage = `url(${loginDesktopUrl})`; } </script>
内容的提问来源于stack exchange,提问作者فوزي الصويمل Fawzi Alswaimil
相关产品推荐
相关产品推荐

