如何将variables从玉模板文件传递给脚本文件?

我遇到了一个在jade模板文件(index.jade)中声明的variables(config)没有传递给javascript文件的麻烦,然后我的javascript崩溃。 这里是文件(views / index.jade):

h1 #{title} script(src='./socket.io/socket.io.js') script(type='text/javascript') var config = {}; config.address = '#{address}'; config.port = '#{port}'; script(src='./javascripts/app.js') 

这是我的app.js(服务器端)的一部分:

  app.use(express.bodyParser()); app.use(express.methodOverride()); app.use(app.router); app.use(express.static(__dirname + '/public')); }); app.configure('development', function(){ app.set('address', 'localhost'); app.use(express.errorHandler({ dumpExceptions: true, showStack: true })); }); app.configure('production', function(){ app.use(express.errorHandler()); }); // Routes app.get('/', function(req, res){ res.render('index', { address: app.settings.address, port: app.settings.port }); }); if (!module.parent) { app.listen(app.settings.port); console.log("Server listening on port %d", app.settings.port); } // Start my Socket.io app and pass in the socket require('./socketapp').start(io.listen(app)); 

这里是我的JavaScript文件的一部分崩溃(公共/ javascripts / app.js):

 (function() { var socket = new io.Socket(config.address, {port: config.port, rememberTransport: false}); 

我在localhost(我自己的机器)上运行开发模式(NODE_ENV =开发)的网站。 我正在使用node-inspector进行debugging,这告诉我在public / javascripts / app.js中configurationvariables是未定义的。

有任何想法吗?? 谢谢!!

有点晚了,但…

 script. loginName="#{login}"; 

这在我的脚本中工作正常。 在Express中,我正在这样做:

 exports.index = function(req, res){ res.render( 'index', { layout:false, login: req.session.login } ); }; 

我猜最新的玉器是不一样的?

芝加哥商业交易所。

编辑:添加“。” 在脚本之后防止玉警告。

!{}是用于非转义的代码插值,它更适合于对象

 script var data = !{JSON.stringify(data).replace(/<\//g, '<\\/')} { foo: 'bar' } // becomes: <script>var data = {"foo":"bar"}</script> { foo: 'bar</script><script>alert("xss")//' } // becomes: <script>var data = {"foo":"bar<\/script><script>alert(\"xss\")//"}</script> 

这个想法是为了防止攻击者:

  1. 打破variables: JSON.stringify转义引号
  2. 打破脚本标记:如果variables内容(如果来自数据库的话可能无法控制)有一个</script>string,replace语句将会处理它

https://github.com/pugjs/pug/blob/355d3dae/examples/dynamicscript.pug


#{}是用于转义string插值的 ,只有在使用string时才适用。 它不适用于对象

 script var data = #{JSON.stringify(data)} //=> <script>var data = {&quot;foo&quot;:&quot;bar&quot;}</script> 

看到这个问题: JADE + EXPRESS:在内联JS代码(客户端)迭代对象?

我有同样的问题。 Jade不会将JavaScript中的局部variables(或根本没有做任何模板)传递给JavaScript脚本,它只是将整个块作为文本文本传递。 如果你在脚本标签上面的Jade文件中使用局部variables的地址和端口,他们应该显示出来。

可能的解决scheme在上面链接到的问题中列出,但是您可以: – 将每行都作为未转义的文本(每行的开始处!=),并且简单地在每一行javascript之前放置“ – ”局部variables,或: – 通过DOM元素传递variables,并通过JQuery访问(丑陋)

有没有更好的办法? 看来Jade的创build者并不想要多行JavaScript支持,就像GitHub中的这个线程所示: https : //github.com/visionmedia/jade/pull/405

以下是我如何解决这个问题(使用MEAN衍生物)

我的变数:

 { NODE_ENV : development, ... ui_varables { var1: one, var2: two } } 

首先,我必须确保必要的configurationvariables被传递。 MEAN使用节点nconf软件包,默认情况下设置为限制从环境传递的variables。 我必须补救:

configuration/ config.js:

原版的:

 nconf.argv() .env(['PORT', 'NODE_ENV', 'FORCE_DB_SYNC'] ) // Load only these environment variables .defaults({ store: { NODE_ENV: 'development' } }); 

修改后:

 nconf.argv() .env('__') // Load ALL environment variables // double-underscore replaces : as a way to denote hierarchy .defaults({ store: { NODE_ENV: 'development' } }); 

现在我可以像这样设置我的variables:

 export ui_varables__var1=first-value export ui_varables__var2=second-value 

注:我将“heirarchy指标”重置为“__”(双下划线),因为它的默认值是“:”,这使得variables更难从bash中设置。 看到这个线程的另一篇文章。

现在,玉器部分:接下来的价值需要被呈现,以便JavaScript可以在客户端拿起它们。 将这些值写入索引文件的直接方法。 因为这是一个单页面的应用(angular度),所以这个页面总是先加载。 我想理想情况下,这应该是一个JavaScript包含文件(只是为了保持干净),但这是一个演示很好。

应用程序/控制器/ index.js:

 'use strict'; var config = require('../../config/config'); exports.render = function(req, res) { res.render('index', { user: req.user ? JSON.stringify(req.user) : "null", //new lines follow: config_defaults : { ui_defaults: JSON.stringify(config.configwriter_ui).replace(/<\//g, '<\\/') //NOTE: the replace is xss prevention } }); }; 

应用程序/视图/ index.jade:

 extends layouts/default block content section(ui-view) script(type="text/javascript"). window.user = !{user}; //new line here defaults = !{config_defaults.ui_defaults}; 

在我提交的HTML中,这给了我一个很好的小脚本:

 <script type="text/javascript"> window.user = null; defaults = {"var1":"first-value","var2:"second-value"}; </script> 

从这个angular度来看,使用代码很容易。