如何在EJS模板中运行JS函数- Express, EJS和UIkit



我得到UIkit is not defined,虽然JS在头中加载。甚至alert也不起作用。如何解决这个问题?

EJS索引模板-

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="css/uikit.min.css" />
<script src="js/uikit.min.js"></script>
<script src="js/uikit-icons.min.js"></script>
<title>Site</title>
</head>
<body>
<% if (message) {%>
<%= UIkit.notification(message) %>
<% }; %>
</body>
</html>

Express app JS

var message = 'Error - not found';
//routes
app.get('/', (request, response) => {
response.render('index', {message: message});
}

误差

17|     <% if (message) {%>
>> 18|         <%= UIkit.notification(message) %>
19|     <% }; %>
20|             <div class="uk-width-1-1">

UIkit is not defined

尝试错误提示

17|     <% if (message) {%>
>> 18|         <%= alert('test') %>
19|     <% }; %>

20|             <div class="uk-width-1-1">

alert is not defined

对于哪些代码在服务器上运行,哪些代码在客户端上运行,似乎有些混淆。

在您的设置中,EJS在Node服务器上运行,并构建一个HTML字符串,该字符串最终被发送到客户机,并在客户机的浏览器中执行。EJS<%= ... >语法允许您在服务器上的Node上下文中评估JS表达式,而不是在浏览器中,允许您将动态内容注入HTML字符串。

这里,<%= alert() =>表示"在服务器上调用Node的alert函数并将返回值注入模板"。但这没有意义——Node没有这样的alert()函数,也不能访问可能包含在<script>中的任何内容。在EJS完成HTML字符串的构建并将其发送给客户端之后,所有这些东西都将无法使用。

可能你想要做的是注入字符串代表你想要调用的函数到模板中:

eval(ejs.render(`<%= "alert(42)" %>`));
<script src="https://unpkg.com/ejs@3.1.6/ejs.min.js"></script>

而不是失败的代码:

window.alert = undefined; // simulate Node, which has no alert()
console.log(ejs.render(`<%= alert(42) %>`)); // fail, trying to call undef func
<script src="https://unpkg.com/ejs@3.1.6/ejs.min.js"></script>

在上面的例子中,字符串"alert(42)"被注入到模板中并发送给"客户端",eval()在那里调用它,大致模拟脚本最终将如何被评估。

无论如何,可能有一种更好的方法来实现有条件地设置函数调用的结果,但是弄清楚这个概念是战斗的99%。

例如,这样的语法也是可能的:

const template = `
<% if (message) {%>
alert("<%= message %>")
<% }; %>
`;
eval(ejs.render(template, {message: "hey"}));
<script src="https://unpkg.com/ejs@3.1.6/ejs.min.js"></script>

小测验:如果你用alert(message)替换alert("<%= message %>")在上面的代码,它会工作吗?为什么或者为什么不呢?

如果您能回答这个问题,那么您可能就理解了在EJS运行时与评估EJS输出之间的区别。

注意:eval纯粹是为了方便/教学目的,这里只用于模拟客户端评估HTML脚本;我并不提倡在真正的应用中使用它!

我假设您已经安装了带有npm install ejs的EJS。

确保在你的express应用中有以下中间件(作为初学者,我总是错过这个中间件):

app.set("view engine", "ejs");

就alert()而言,正如其他人所指出的,alert()在服务器上运行时不起作用。在客户端呈现之前,EJS通过其引擎转换为HTML。

<body onload="UIkit.notification({message:'<%=message%>'})">解决

相关内容

  • 没有找到相关文章