জেড টেম্পলেট ফাইল থেকে স্ক্রিপ্ট ফাইলে ভেরিয়েবল কীভাবে পাস করবেন?


119

জেড স্ক্রিপ্ট ফাইলে পাস করা হয়নি এমন একটি জেড টেম্পলেট ফাইল (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.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));

এবং এখানে আমার জাভাস্ক্রিপ্ট ফাইলটির একটি অংশ ক্র্যাশ হয়ে গেছে (সর্বজনীন / জাভাস্ক্রিপ্ট / অ্যাপ্লিকেশন):

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

আমি লোকালহোস্টে (আমার নিজের মেশিন) ডেভলপমেন্ট মোডে (NODE_ENV = বিকাশ) সাইট চালাচ্ছি। আমি ডিবাগিংয়ের জন্য নোড-ইন্সপেক্টর ব্যবহার করছি, যা আমাকে জানিয়েছিল যে কনফিগার ভেরিয়েবলটি সর্বজনীন / জাভাস্ক্রিপ্ট / অ্যাপ.জেএস-এ সংজ্ঞায়িত।

কোন ধারনা?? ধন্যবাদ !!


উত্তর:


174

এটা একটা ব্যাপার একটু দেরী কিন্তু ...

script.
  loginName="#{login}";

এটি আমার স্ক্রিপ্টে কাজ করছে। এক্সপ্রেসে, আমি এটি করছি:

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

আমার ধারণা সর্বশেষ জেডটি কি আলাদা?

Merc।

সম্পাদনা: যুক্ত "।" জেড সতর্কতা রোধ করতে স্ক্রিপ্টের পরে।


1
উত্তর গ্রহণের জন্য ধন্যবাদ! তো, আপনার কোডটি নিয়ে আসল সমস্যাটি কী ছিল ?
Merc

হ্যাঁ, টেমপ্লেটে স্থানীয় ভেরিয়েবলটি উদ্ধৃতিতে এবং # {ator সূচককে মোড়ানো করে আমি এই কাজটি পেয়েছি।
Askdesigners

এই উত্তরটি বিপজ্জনক, লেগিনেরেফ্লেক্সের উত্তরটি সঠিকভাবে স্ট্রিংটিকে এনকোড করেছে (লগইন নামের নতুন লাইনে কোড কার্যকর করার অনুমতি দিতে পারে)।
পল গ্রোভ

সুতরাং সমস্যাটি কেবল একক উক্তি ছিল যখন ডাবল প্রত্যাশিত, তাই না?
আগস্টিন রিডিংগার

আমার জন্য বিষয়টি বিন্দু ছিল। আমার এটি স্ক্রিপ্ট ব্লকের শেষে ছিল। "স্ক্রিপ্ট" কীওয়ার্ডের পরে ডটের সাথে এটি একটি কবজির মতো কাজ করে। ধন্যবাদ!
মিরকো

102

!{}অপরিবর্তিত কোড ইন্টারপোলেশন জন্য যা বস্তুর জন্য আরও উপযুক্ত

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. স্ক্রিপ্ট ট্যাগটি ভেঙে ফেলা: যদি চলক বিষয়বস্তু (যদি আপনি প্রাক্তন ডাটাবেস থেকে আসে তবে আপনি নিয়ন্ত্রণ করতে পারবেন না) এর </script>স্ট্রিং থাকে, প্রতিস্থাপনের স্টেটমেন্টটি এর যত্ন নেবে

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


#{}পলান জন্য স্ট্রিং ক্ষেপক , যা উপযুক্ত আপনি স্ট্রিং সাথে কাজ করছি শুধুমাত্র যদি হয়। এটি বস্তুর সাথে কাজ করে না

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

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

1
দুর্দান্ত উত্তর! আমি এই বিষয়টি 20+ মিনিট ধরে অনুসন্ধান করছি এবং অন্য কোনও উত্তরের মধ্যে পার্থক্যটি বলা হয়নি! {} এবং # difference {! পুরো সময়টি আমি কেবল ভেবেছিলাম! {] হ'ল # {of এর অবমূল্যায়ন সমতুল্য ... আবার ধন্যবাদ Thanks
প্যাট্রিক ই

শীর্ষে! দুর্দান্ত উত্তর।
শে

দুর্দান্ত উত্তর, এবং এটি বস্তুর জন্য কাজ করে! বিটিডব্লিউ, JSONএকটি বিশ্বব্যাপী অবজেক্ট? দেখে মনে হচ্ছে এটি অন্য কোনও লাইব্রেরি আমদানি না করেই কাজ করবে। যদি তা হয় তবে ব্রাউজার সমর্থন সম্পর্কে কী?
ছারভে

@chharvey তাদেরকে JSON (তারিখ বা ম্যাথ মত) একটি JavaScript ভাষা builtin, সমস্ত ব্রাউজার এটা সমর্থন নেই।
laggingreflex

1
এটি সর্বোত্তম উত্তর হিসাবে সম্মত, তবে আমি মনে করি না যে এটি সম্ভাব্য-বিপজ্জনক স্ট্রিং থেকে বাঁচার জন্য সঠিক জায়গা। আইএমও replaceএই কোডটিতে কল বাদ দেওয়া ভাল , এবং এই মানটি অন্য কোনও ইনপুট এর মতো আচরণ করা ভাল । JSON.stringify বৈধ জাভাস্ক্রিপ্ট উত্পাদন (বা ব্যর্থ) উত্পাদন গ্যারান্টিযুক্ত, এবং আপনার মেমরির মধ্যে এই সম্ভাব্য-বিপজ্জনক মান পরে আপনি ব্যবহারের আগে প্রয়োজন হিসাবে এটি স্যানিটাইজেশন নিশ্চিত করতে পারেন।
রিলে লার্ক

9

আমার ক্ষেত্রে, আমি কোনও এক্সপ্রেস রুট (ওপিএস সেটআপের অনুরূপ) দিয়ে কোনও টেমপ্লেটে কোনও বস্তুটি পাস করার চেষ্টা করছিলাম। তারপরে আমি সেই বস্তুকে একটি ফাংশনে পাস করতে চেয়েছিলাম যা আমি প্যাগ টেম্পলেটটিতে একটি স্ক্রিপ্ট ট্যাগের মাধ্যমে কল করেছিলাম। যদিও লেগিনিরেফ্লেক্সের উত্তরটি আমাকে কাছে পেয়েছে তবে আমি নিম্নলিখিতটি দিয়ে শেষ করেছি:

script.
    var data = JSON.parse('!{JSON.stringify(routeObj)}');
    funcName(data)

এটি নিশ্চিত করে যে ফাংশনটি ডিসরিয়ালাইজ করার পরিবর্তে প্রত্যাশাকে প্রত্যাশা অনুযায়ী পাস করা হয়েছিল। এছাড়াও, অন্যান্য উত্তরগুলি আদিমগুলির সাথে ভাল কাজ করেছে বলে মনে হয়েছিল, তবে অ্যারেগুলি যখন বস্তুর সাথে পাস করা হয়েছিল তখন তারা স্ট্রিংয়ের মান হিসাবে পার্স করা হয়েছিল।


7

আপনি যদি আমার মতো হন এবং আপনি ভেরিয়েবলগুলি পাস করার এই পদ্ধতিটি ব্যবহার করেন তবে এখানে একটি লিখন-কম-কোড সমাধান রয়েছে।

আপনার নোড.জেএস রুটে, নামক কোনও বস্তুতে ভেরিয়েবলগুলি পাস করুন window:

router.get('/', function (req, res, next) {
    res.render('index', {
        window: {
            instance: instance
        }
    });
});

তারপরে আপনার পগ / জেড লেআউট ফাইলে (ঠিক আগে block content) আপনি এগুলি এড়িয়ে যাবেন :

if window
    each object, key in window
        script.
            window.!{key} = !{JSON.stringify(object)};

আমার লেআউট.পাগ ফাইলটি প্রতিটি পগ ফাইলের সাথে লোড হওয়ার সাথে সাথে আমার ভেরিয়েবলগুলি বারবার 'আমদানি' করার দরকার নেই।

এইভাবে সমস্ত ভেরিয়েবল / অবজেক্টগুলি আপনার ব্রাউজারের windowআসল windowঅবজেক্টে 'ম্যাজিক্যালি' শেষ হয়েছে যেখানে আপনি এগুলি রি্যাক্টজ, কৌণিক, ... বা ভ্যানিলা জাভাস্ক্রিপ্টে ব্যবহার করতে পারেন।


1
এটি আমি দেখেছি সেরা উত্তর।
তোহির

3

আমি এখানে এটি কীভাবে সম্বোধন করেছি (একটি MEAN ডেরিভেটিভ ব্যবহার করে)

আমার পরিবর্তনশীল:

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

প্রথমে আমাকে নিশ্চিত করতে হয়েছিল যে প্রয়োজনীয় কনফিগার ভেরিয়েবলগুলি পাস হচ্ছে। MEAN নোড এনকনফ প্যাকেজটি ব্যবহার করে এবং ডিফল্টরূপে সেট করা হয় যা পরিবেশ থেকে ভেরিয়েবলগুলি পাস করতে পারে limit আমাকে এর প্রতিকার করতে হয়েছিল:

কনফিগ / 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

দ্রষ্টব্য: আমি "উত্তরাধিকার সূচক "টিকে" __ "(ডাবল আন্ডারস্কোর) এ পুনরায় সেট করেছি কারণ এর ডিফল্ট ছিল": ", যা ব্যাশ থেকে সেট করতে ভেরিয়েবলকে আরও কঠিন করে তোলে। এই থ্রেডে অন্য পোস্ট দেখুন।

এখন জেড অংশ: পরবর্তী মানগুলি রেন্ডার করা দরকার, যাতে জাভাস্ক্রিপ্ট তাদের ক্লায়েন্টের পাশে নিতে পারে। ইনডেক্স ফাইলে এই মানগুলি লেখার একটি সহজ উপায়। এটি একটি পৃষ্ঠার অ্যাপ (কৌণিক) হওয়ায় এই পৃষ্ঠাটি সর্বদা প্রথমে লোড হয়। আমি মনে করি আদর্শভাবে এটি একটি জাভাস্ক্রিপ্ট হওয়া উচিত ফাইল অন্তর্ভুক্ত (কেবল জিনিস পরিষ্কার রাখতে) তবে এটি একটি ডেমোর জন্য ভাল।

অ্যাপ্লিকেশন / কন্ট্রোলার / 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};

আমার রেন্ডার করা এইচটিএমএল এ, এটি আমাকে একটি দুর্দান্ত ছোট স্ক্রিপ্ট দেয়:

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

এই দিক থেকে কৌনিক কোডটি ব্যবহার করা সহজ।


গ্রহণযোগ্য উত্তরটি ইতিমধ্যে যা বলেছে এটি বলার এটি খুব দীর্ঘ বাতাসের উপায়। তদতিরিক্ত, MEAN, nconf ইত্যাদি উল্লেখ অপ্রাসঙ্গিক। প্রশ্নটি কীভাবে ক্লায়েন্টকে ভেরিয়েবলগুলি পাস করবেন সে সম্পর্কে নয়, আপনি কীভাবে আপনার ডেভ স্ট্যাকটি করেছিলেন তা নয়। যদিও হতাশ নয়, যেহেতু আপনি এখনও এই উত্তরে প্রচুর প্রচেষ্টা করেছেন।
মিচিফ


2

এই প্রশ্নটি দেখুন: জ্যাড + এক্সপ্রেস: ইনলাইন জেএস কোডে (ক্লায়েন্ট-সাইড) ওভার অবজেক্টে আইট্রেট করা?

আমারও একই সমস্যা হচ্ছে জ্যাড জাভাস্ক্রিপ্ট স্ক্রিপ্টগুলিতে স্থানীয় ভেরিয়েবলগুলি (বা কোনওরকম টেম্প্লেটিং করুন) পাস করে না, এটি পুরো ব্লককে কেবল আক্ষরিক পাঠ্য হিসাবে পাস করে। আপনি যদি স্ক্রিপ্ট ট্যাগের উপরে আপনার জেড ফাইলে স্থানীয় ভেরিয়েবলগুলি 'ঠিকানা' এবং 'পোর্ট' ব্যবহার করেন তবে তাদের প্রদর্শিত হওয়া উচিত।

আমি উপরে উল্লিখিত প্রশ্নের সাথে সম্ভাব্য সমাধানগুলি তালিকাভুক্ত করা হয়েছে তবে আপনি তা করতে পারেন: - প্রতিটি লাইনকে অপরিবর্তিত পাঠ্য হিসাবে পাস করুন (! = প্রতিটি লাইনের শুরুতে), এবং জাভাস্ক্রিপ্টের প্রতিটি লাইনের আগে "-" লিখুন যা একটি ব্যবহার করে স্থানীয় পরিবর্তনশীল, বা: - একটি ডোম উপাদান মাধ্যমে ভেরিয়েবল পাস এবং JQuery (কুৎসিত) মাধ্যমে অ্যাক্সেস

এর চেয়ে ভাল আর কোন উপায় নেই? দেখে মনে হচ্ছে গ্যাডহাবের এই থ্রেড অনুসারে জেডের নির্মাতারা মাল্টলাইন জাভাস্ক্রিপ্ট সমর্থন চান না: https://github.com/visionmedia/jade/pull/405

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.