2012-01-02 116 views
91

我在jade模板文件(index.jade)中聲明的變量(config)沒有傳遞給javascript文件,導致我的javascript崩潰。下面是該文件(意見/ 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文件的一部分崩潰(公共/ Java腳本/ app.js):

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

我運行在本地主機上的發展模式網站(NODE_ENV =開發)(我自己的機器)。我使用node-inspector進行調試,它告訴我在public/javascripts/app.js中配置變量是未定義的。

任何想法??謝謝!!

+0

[ExpressJS將變量傳遞給JavaScript]可能的副本(http://stackoverflow.com/questions/9268951/expressjs-pass-variables-to-javascript) – laggingreflex 2015-02-03 22:37:13

回答

134

這是一個有點但是...

script. 
    loginName="#{login}"; 

這是工作在我的腳本罰款。在快遞,我這樣做:

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

我猜最新的玉是不同的?

Merc。

edit:added「。」在腳本之後防止玉警告。

+1

感謝您接受答案!那麼,你的代碼有哪些_actual_問題? – Merc 2012-08-17 00:23:55

+0

是的,我也通過在模板中用引號和#{}指示器包裹局部變量來得到這個工作。 – Askdesigners 2015-02-11 20:02:01

+0

這個回答很危險,lagginreflex的答案正確地編碼了字符串(登錄名中的換行符可能允許執行代碼)。 – 2016-11-08 18:13:12

2

看到這個問題:JADE + EXPRESS: Iterating over object in inline JS code (client-side)?

我有同樣的問題。 Jade不會將JavaScript中的局部變量(或根本不做任何模板)傳遞給JavaScript腳本,它只是將整個塊作爲文本文本傳遞。如果您在腳本標記上方的Jade文件中使用本地變量的「地址」和「端口」,則應顯示它們。

可能的解決方案列在上面鏈接的問題中,但您可以: - 將每行都作爲未轉義的文本(!=在每行的開始處),並且只需在每行之前放置「 - 」使用本地變量的javascript,或者: - 通過dom元素傳遞變量並通過JQuery訪問(醜陋)

有沒有更好的方法?這似乎玉的創造者不想多的JavaScript支持,在GitHub上顯示此線程:https://github.com/visionmedia/jade/pull/405

78

!{}unescaped code插值,這是更適合對象

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. 打出來的變量:JSON.stringify逃逸引號
  2. 打破腳本標記:如果變量co ntents(你可能無法控制是否來自數據庫,例如。)具有</script>字符串替換語句將照顧它

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


#{}是逃脫string interpolation,這是唯一的,如果你處理字符串合適。 它不使用對象

script var data = #{JSON.stringify(data)} 

//=> <script>var data = {&quot;foo&quot;:&quot;bar&quot;}</script> 
+1

非常感謝! – Sgnl 2015-03-01 06:32:46

+0

優秀的答案!我一直在尋找這個主題20分鐘以上,沒有其他答案說明!{}和#{}之間的區別。整個過程我只是認爲!{}是#{}的棄用等價物......再次感謝。 – 2015-09-13 23:05:20

+0

非常感謝! – 2015-10-26 12:17:09

0

以下是我解決了這個(使用平均衍生物)

我的變量:

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

首先,我必須確保必要的正在傳遞配置變量。 MEAN使用節點nconf軟件包,默認情況下設置爲限制從環境傳遞的變量。我不得不補救:

的config/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' 
    } 
}); 

現在,我可以把我的變量是這樣的:

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

注意:我將「heirarchy指示符」重置爲「__」(雙下劃線),因爲它的默認值是「:」,這使變量更難以從bash中設置。請參閱此主題上的另一篇文章。

現在的玉器部分: 接下來需要渲染的值,以便JavaScript可以在客戶端接他們。將這些值寫入索引文件的直接方法。因爲這是一個單頁面的應用程序(角度),所以這個頁面總是先加載。我認爲理想情況下,這應該是一個JavaScript包含文件(只是爲了保持乾淨),但這對演示很有用。

的app/controllers/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>   

從這一點很容易使用代碼。

+0

這是一個非常冗長的方式來說明接受的答案已經說了什麼。而且,提到MEAN,nconf等是無關緊要的。問題是關於如何將變量傳遞給客戶端,而不是關於如何執行你的開發堆棧。儘管如此,因爲你仍然在這個答案中付出了很多努力。 – Mrchief 2016-11-16 14:06:29

+0

過於複雜 – andygoestohollywood 2017-09-07 07:20:32

相關問題