如何将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>
这个想法是为了防止攻击者:
- 打破variables:
JSON.stringify
转义引号 - 打破脚本标记:如果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 = {"foo":"bar"}</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度来看,使用代码很容易。