2012-01-02 39 views
91

Tôi đang gặp sự cố với biến (config) được khai báo trong tệp mẫu ngọc bích (index.jade) không được chuyển đến tệp javascript, sau đó làm lỗi javascript của tôi. Dưới đây là file (views/index.jade):Làm thế nào để chuyển biến từ tệp mẫu ngọc bích sang tệp tập lệnh?

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

đây là một phần của app.js của tôi (server side):

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

Và đây là một phần của tập tin của tôi rằng javascript tai nạn (công cộng/Javascripts/app.js):

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

tôi đang chạy các trang web trên chế độ phát triển (NODE_ENV = phát triển) trên localhost (máy của riêng tôi). Tôi đang sử dụng trình kiểm tra nút để gỡ lỗi, cho tôi biết rằng biến cấu hình không được xác định trong public/javascripts/app.js.

Bất kỳ ý tưởng nào ?? Cảm ơn!!

+0

có thể trùng lặp của [Biến ExpressJS Pass thành JavaScript] (http://stackoverflow.com/questions/9268951/expressjs-pass-variables-to-javascript) – laggingreflex

Trả lời

134

Đó là một chút muộn nhưng ...

script. 
    loginName="#{login}"; 

này đang làm việc tốt trong kịch bản của tôi . Trong Express, tôi đang làm điều này:

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

Tôi đoán ngọc mới nhất là khác nhau?

Merc.

chỉnh sửa: đã thêm "." sau khi kịch bản để ngăn chặn cảnh báo Jade.

+1

Cảm ơn bạn đã chấp nhận câu trả lời! Vì vậy, vấn đề _actual_ với mã của bạn là gì? – Merc

+0

Có, tôi đã làm việc này cũng bằng cách gói biến cục bộ trong mẫu trong dấu ngoặc kép và chỉ báo # {}. – Askdesigners

+0

Câu trả lời này là nguy hiểm, câu trả lời của lagginreflex mã hóa chính xác chuỗi (các dòng mới trong tên đăng nhập có thể cho phép thực thi mã). –

2

Xem câu hỏi này: JADE + EXPRESS: Iterating over object in inline JS code (client-side)?

Tôi đang gặp vấn đề tương tự. Jade không vượt qua các biến cục bộ (hoặc làm bất kỳ templating nào cả) cho các script javascript, nó chỉ đơn giản là chuyển toàn bộ khối vào dưới dạng văn bản chữ. Nếu bạn sử dụng các biến địa phương 'địa chỉ' và 'cổng' trong tập tin Jade của bạn trên thẻ script họ sẽ hiển thị.

Các giải pháp có thể được liệt kê trong câu hỏi tôi đã liên kết ở trên, nhưng bạn có thể: - chuyển mỗi dòng dưới dạng văn bản chưa thoát (! = Ở đầu mỗi dòng) và chỉ cần đặt "-" trước mỗi dòng của javascript sử dụng biến cục bộ hoặc: - Chuyển các biến thông qua phần tử dom và truy cập qua JQuery (xấu xí)

Không có cách nào tốt hơn? Có vẻ như những người sáng tạo của Jade không muốn multiline hỗ trợ javascript, như thể hiện bởi chủ đề này trong GitHub: https://github.com/visionmedia/jade/pull/405

78

!{} là dành cho unescaped code suy, đó là phù hợp hơn cho đối tượng

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> 

Ý tưởng là để ngăn chặn những kẻ tấn công để:

  1. lao ra của biến: JSON.stringify thoát các dấu ngoặc kép
  2. Thoát khỏi thẻ tập lệnh: nếu biến co ntents (mà bạn có thể không kiểm soát được nếu xuất phát từ cơ sở dữ liệu cho ex.) Có một chuỗi </script>, báo cáo kết quả thay thế sẽ chăm sóc nó

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


#{} là cho thoát string interpolation, mà chỉ phù hợp nếu bạn đang làm việc với chuỗi. Nó không hoạt động với các đối tượng

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

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

Cảm ơn rất nhiều! – Sgnl

+0

Câu trả lời hay! Tôi đã tìm kiếm chủ đề này trong hơn 20 phút và không có câu trả lời nào khác cho biết sự khác biệt giữa! {} Và # {}. Toàn bộ thời gian này tôi chỉ nghĩ! {] Là tương đương không được chấp nhận của # {} ... Cảm ơn một lần nữa. –

+0

Cảm ơn rất nhiều !! –

0

Đây là cách tôi giải quyết này (sử dụng một dẫn xuất MEAN)

biến của tôi:

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

Trước tiên tôi phải chắc chắn rằng cần thiết biến cấu hình đã được chuyển. MEAN sử dụng gói nconf nút, và theo mặc định được thiết lập để giới hạn các biến nào được truyền từ môi trường. Tôi đã phải khắc phục rằng:

config/config.js:

gốc:

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

sau khi sửa đổi:

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

Bây giờ tôi có thể thiết lập các biến của tôi như thế này:

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

Lưu ý: Tôi đặt lại "chỉ báo heirarchy" thành "__" (dấu gạch dưới kép) vì mặc định là ":", làm cho các biến khó đặt hơn từ bash. Xem một bài đăng khác trên chủ đề này.

Bây giờ phần ngọc bích: Tiếp theo các giá trị cần được hiển thị, để javascript có thể chọn chúng ở phía máy khách. Một cách đơn giản để viết các giá trị này vào tệp chỉ mục. Bởi vì đây là một ứng dụng một trang (góc), nên trang này luôn được tải trước. Tôi nghĩ rằng lý tưởng này nên là một tập tin javascript bao gồm (chỉ để giữ cho mọi thứ sạch sẽ), nhưng điều này là tốt cho một bản demo.

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

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

Trong html rendered của tôi, điều này mang lại cho tôi một kịch bản tốt đẹp chút :

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

Từ điểm này thật dễ dàng để sử dụng mã.

+0

Đây là một cách rất dài để nói câu trả lời được chấp nhận đã nói. Hơn nữa, đề cập đến MEAN, nconf vv là không liên quan. Câu hỏi đặt ra là làm thế nào để chuyển các biến cho máy khách, chứ không phải về cách bạn đã thực hiện phân đoạn dev của bạn. Không downvoting mặc dù, kể từ khi bạn vẫn đặt trong rất nhiều nỗ lực trong câu trả lời này. – Mrchief

+0

quá phức tạp – andygoestohollywood

Các vấn đề liên quan