Express/Node.js: 将自定义JavaScript以响应方式呈现

6

在我的应用程序中,我需要提供一个API(类似于Google Maps JavaScript API),通过该API,我可以发送一些自定义JavaScript代码(包含一些会话和请求相关的信息)作为响应。然后使用这些JavaScript代码在UI上绘制一些图表。我正在使用Express和Jade作为模板引擎。我目前正在使用的代码是:

app.use('/graph',function(req, res){
   //send out graph data
   var var_name = req.session.var_name //fetch something from session
   var graphData = fetchGraphData(req.query.graph); //function that fetches graph data
   res.contentType("text/javascript");
   res.render(__dirname + '/views/graph.jade', {
     title: "Title", queryStr: JSON.stringify({var_name: var_name, graphData: graphData  })
   });
});

并且jade文件:

|  some_var_name = {
|       initGraph : function(divId){
|       //some code here
|       var graphData = !{graphData}
|       // do something                               

作为解决方法,我已经在jade文件的每一行前面添加了|,这样jade会将文本解析为普通文本,并不会添加任何html标签!它能正常工作,但是否有更简洁的方法呢?解决方案可以使用Jade,也可以不用!


我不知道实际上需要多少模板,但您仍然可以使用res.send发送任何字符串。 - TheHippo
@TheHippo:感谢您的回复!但我想把响应数据组织在文件中,因为会有很多这样的操作,并且文件也相当长! - Anuj Arora
3个回答

6
你应该了解一下 underscore templates。我认为对于生成任意文本输出,这将更加干净。Jade是专门用于渲染HTML的。
你还可以尝试使用MustacheHandlebars
根据您的评论,我看到您希望继续使用res.render来渲染模板。consolodate.js为Express添加了对所有主要模板引擎的支持,包括@TheHippo提到的Underscore模板,Handlebars,Mustache和Dust。

同时,dust也应该可以很好地工作,因为它是语言无关的。(不仅限于HTML模板) - TheHippo
感谢您的建议。我选择了Handlebars。现在看起来更加清晰! - Anuj Arora

1
您可以尝试在模板之外的单独模块中定义需要发送到浏览器的JavaScript函数,这可能是从“关注点分离”的角度来看更正确的方式。此外,如果函数在单独的模块中定义,则可以在服务器和浏览器中都使用它们。
然后,您可以使用其toString()方法将函数转换为字符串,无论是在调用模板的函数中还是在模板内部直接进行转换,如果模板支持纯JavaScript(这是underscore、EJS和doT模板的情况,我尝试了underscore和EJS,最终选择了doT,它不仅是最快的,而且非常多才多艺-请查看它):
JS代码:
// if you send the same functions you may want to convert them to strings in advance
var data = {
    funcStr: func.toString();
};
res.render(view, data);

模板(doT):
<script type="text/javascript">
    func = {{= it.funcStr }};

    // now you can call it here if you want but I would use 
    // separate JavaScript files
    func();
</script>

我使用它将预编译的模板与页面一起在第一个页面加载时发送到浏览器,但我认为在你的情况下也可以使用它。
另外一个问题是,为什么不能将所有这些函数捆绑在一个单独的JavaScript模块中,并像正常脚本文件一样加载它们?

我要公开的API在基本的HTTP身份验证后只返回一个JavaScript文件,js响应包含一些授权信息和一些用于与socket.io交互的请求参数。js响应类似于Google Maps API。响应只能是1个js文件,因此除非在呈现响应之前将所有单独的文件编译成一个文件,否则无法将函数捆绑在单独的文件中! - Anuj Arora

1

你还在编辑那个句子,对吗?另外,请不要只提供一个包/库的名称。请示范它是如何解决问题的。 - Yunnosch

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接