2012-01-02 13 views
91

Sto riscontrando problemi con una variabile (config) dichiarata in un file modello di jade (index.jade) che non viene passato a un file javascript, il che rende quindi il mio javascript in crash. Ecco il file (vista/index.jade):Come passare la variabile dal file modello di giada a un file di script?

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') 

Ecco una parte delle mie app.js (lato server):

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)); 

E qui è una parte della mia javascript file crash (/ javascripts/app.js pubblici):

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

sto correndo il sito su modalità di sviluppo (NODE_ENV = sviluppo) su localhost (la mia macchina). Sto usando node-inspector per il debug, che mi ha detto che la variabile di configurazione non è definita in public/javascripts/app.js.

Qualche idea ?? Grazie!!

+0

possibile duplicato di [Variabili Pass ExpressJS in JavaScript] (http://stackoverflow.com/questions/9268951/expressjs-pass-variables-to-javascript) – laggingreflex

risposta

134

E 'un po' in ritardo ma ...

script. 
    loginName="#{login}"; 

Questo sta lavorando bene nel mio script . In Express, sto facendo questo:

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

Immagino che l'ultima giada sia diversa?

Merc.

modifica: aggiunta "." dopo lo script per prevenire l'avviso di giada.

+1

Grazie per aver accettato la risposta! Quindi, qual è stato il problema _actual_ con il tuo codice? – Merc

+0

Sì, ho funzionato anche avvolgendo la variabile locale nel modello tra virgolette e l'indicatore # {}. – Askdesigners

+0

Questa risposta è pericolosa, la risposta di lagginreflex codifica correttamente la stringa (i newline nel nome di accesso potrebbero consentire l'esecuzione del codice). –

2

Vai a questa domanda: JADE + EXPRESS: Iterating over object in inline JS code (client-side)?

Sto avendo lo stesso problema. Jade non passa le variabili locali in (o non fa affatto alcun modello) agli script javascript, semplicemente passa l'intero blocco come testo letterale. Se si usano le variabili locali 'indirizzo' e 'porta' nel proprio file Jade sopra il tag dello script, dovrebbero essere mostrati.

Possibili soluzioni sono elencate nella domanda che ho linkato sopra, ma è possibile: - pass ogni riga nel testo come escape (= all'inizio di ogni riga!), E in poche parole "-" prima di ogni linea di javascript che utilizza una variabile locale, oppure: - Passa le variabili attraverso un elemento dom e accedi tramite JQuery (brutto)

Non c'è un modo migliore? Sembra che i creatori di Jade non vogliono più righe supporto javascript, come mostrato da questa discussione in GitHub: https://github.com/visionmedia/jade/pull/405

78

!{} è per unescaped code interpolazione, che è più adatto per oggetti

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> 

L'idea è quella di evitare il malintenzionato di:

  1. uscire variabile: JSON.stringify fughe le virgolette
  2. Break out del tag dello script: se la variabile co ntents (che potresti non essere in grado di controllare se proviene dal database per es.) Ha una stringa </script>, la dichiarazione sostituire si prenderà cura di esso

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


#{} è per sfuggito string interpolation, che è adatto solo se si sta lavorando con le stringhe. E non funziona con oggetti

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

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

Grazie mille! – Sgnl

+0

Ottima risposta! Ho cercato questo argomento per oltre 20 minuti e nessuna altra risposta ha indicato la differenza tra! {} E # {}. Per tutto questo tempo ho pensato! {] Era l'equivalente deprecato di # {} ... Grazie ancora. –

+0

Grazie mille !! –

0

Ecco come ho affrontato questo (usando un derivato media)

mie variabili:

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

Per prima cosa ho dovuto fare in modo che la necessaria le variabili di configurazione venivano passate. MEAN utilizza il pacchetto node nconf e, per impostazione predefinita, è impostato per limitare quali variabili vengono passate dall'ambiente. Ho dovuto porre rimedio a tale:

config/config.js:

originale:

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

dopo le modifiche:

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

ora posso impostare le mie variabili in questo modo:

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

Nota: ho reimpostato "l'indicatore di gerarchia" su "__" (doppio trattino basso) perché il suo valore predefinito era ":", il che rende le variabili più difficili da impostare da bash. Vedi un altro post su questo thread.

Ora la parte di giada: Successivamente i valori devono essere visualizzati, in modo che javascript possa prelevarli dal lato client. Un modo semplice per scrivere questi valori nel file indice. Poiché questa è un'app di una pagina (angolare), questa pagina viene sempre caricata per prima. Penso che idealmente questo dovrebbe essere un file include javascript (solo per mantenere le cose pulite), ma questo è buono per una demo.

app/controller/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 
    } 
    }); 
}; 

app/views/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}; 

Nel mio rendering HTML, questo mi dà un piccolo script bella :

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

Da questo punto è facile per angolare utilizzare il codice.

+0

Questo è un modo molto lungo di dire quello che la risposta accettata già dice. Inoltre, menzionare MEAN, nconf ecc è irrilevante. La domanda è su come passare variabili al client, non su come hai fatto il tuo stack di sviluppo. Non downvoting però, dal momento che hai ancora messo un sacco di sforzo in questa risposta. – Mrchief

+0

eccessivamente complicato – andygoestohollywood

Problemi correlati