जावास्क्रिप्ट फ़ाइलों के लिए पैरामीटर पारित करना


163

अक्सर मेरे पास एक जावास्क्रिप्ट फ़ाइल होगी जिसे मैं उपयोग करना चाहता हूं जिसके लिए मेरे वेब पेज में कुछ चर की आवश्यकता होती है।

तो कोड कुछ इस तरह है:

<script type="text/javascript" src="file.js"></script>
<script type="text/javascript">
   var obj1 = "somevalue";
</script>

लेकिन मैं क्या करना चाहता हूँ:

<script type="text/javascript" 
     src="file.js?obj1=somevalue&obj2=someothervalue"></script>

मैंने विभिन्न तरीकों की कोशिश की और सबसे अच्छा अभी तक इस तरह क्वेरी स्ट्रिंग को पार्स करना है:

var scriptSrc = document.getElementById("myscript").src.toLowerCase();

और फिर मेरे मूल्यों की खोज करें।

मुझे आश्चर्य है कि अगर मेरी स्ट्रिंग को पार्स करने के लिए एक फ़ंक्शन का निर्माण किए बिना ऐसा करने का एक और तरीका है।

क्या आप सभी अन्य तरीकों को जानते हैं?


9
यह एक डुप्लिकेट प्रश्न है ( stackoverflow.com/questions/1017424/… ) और मेरी राय में एक गुमराह डिजाइन। यह आपके पहले चर समाधान (ठीक) का उपयोग करने के लिए बहुत सरल है, या स्क्रिप्ट ने एक फ़ंक्शन को परिभाषित किया है जिसे तब चर (बेहतर) के साथ कहा जाता है।
मैथ्यू Flaschen

मैं एक अद्यतन समाधान की तलाश कर रहा हूँ जो नए ECMAScript 6 की कार्यक्षमता का लाभ उठाता है ... यदि कोई हो
Chef_Code 20

यदि कोई साइट HTTPS है और CSP पूरी तरह से सक्षम है तो किसी भी आंतरिक स्क्रिप्ट का उपयोग करके CSP रिपोर्ट को ट्रिगर किया जाएगा। सीएसपी डॉक्टर में दिए गए कारण यह है कि आंतरिक तत्वों को अनुमति देना इंजेक्शन को आसान बना सकता है।
डेविड स्पेक्टर

जवाबों:


207

मैं यदि संभव हो तो वैश्विक चर का उपयोग नहीं करने की सलाह दूंगा। किसी ऑब्जेक्ट के माध्यम से अपने तर्क पास करने के लिए एक नामस्थान और OOP का उपयोग करें।

यह कोड file.js में है:

var MYLIBRARY = MYLIBRARY || (function(){
    var _args = {}; // private

    return {
        init : function(Args) {
            _args = Args;
            // some other initialising
        },
        helloWorld : function() {
            alert('Hello World! -' + _args[0]);
        }
    };
}());

और अपने HTML फ़ाइल में:

<script type="text/javascript" src="file.js"></script>
<script type="text/javascript">
   MYLIBRARY.init(["somevalue", 1, "controlId"]);
   MYLIBRARY.helloWorld();
</script>

4
@Naeem - जब MYLIBRARY.init (["somevalue", 1, "controlId"]) में फ़ाइल 100% लोड होती है; निष्पादित हो जाता है? शायद हमें इसे डालने के लिए तैयार दस्तावेज़ पर ज़रूरत है?
डेरियस। वी।

2
1) यदि MYLIBRARY मौजूद है तो इसका उपयोग करें या एक नई वस्तु को परिभाषित करें। इरादा एक वैश्विक नाम स्थान बनाने का है, आम तौर पर मैं उप नामस्थानों का उपयोग करूंगा ताकि यह रेखा शीर्ष स्तर के नामस्थान को फिर से परिभाषित करने से बचने में मदद करे। 2) हां, इसने एक सिंगलटन बनाया है।
नईम सरफराज

1
मैंने इस विचार का एक उदाहरण बनाया है: http://plnkr.co/edit/iE0Vr7sszfqrrDIsR8Wi?p=preview
robe007

1
इस अभिव्यक्ति का क्या अर्थ है? var MYLIBRARY = MYLIBRARY || (function(){}());? MYLIBRARYबूलियन मान पर सेट क्यों होना चाहिए ?
एलेक्स

1
@ अलेक्जेंडर, मेरी टिप्पणी के ऊपर देखें stackoverflow.com/questions/2190801/…
Naeem Sarfraz

79

आप मनमानी विशेषताओं के साथ पैरामीटर पास कर सकते हैं। यह हाल के सभी ब्राउज़रों में काम करता है।

<script type="text/javascript" data-my_var_1="some_val_1" data-my_var_2="some_val_2" src="/js/somefile.js"></script>

Somefile.js के अंदर आप इस तरह से चर मान प्राप्त कर सकते हैं:

........

var this_js_script = $('script[src*=somefile]'); // or better regexp to get the file name..

var my_var_1 = this_js_script.attr('data-my_var_1');   
if (typeof my_var_1 === "undefined" ) {
   var my_var_1 = 'some_default_value';
}
alert(my_var_1); // to view the variable value

var my_var_2 = this_js_script.attr('data-my_var_2');   
if (typeof my_var_2 === "undefined" ) {
   var my_var_2 = 'some_default_value';
}
alert(my_var_2); // to view the variable value

...आदि...


1
बहुत अच्छा समाधान, यह भी async विशेषता के साथ काम करता है।
वीरुस्त्रीनी

2
पुराने लेकिन उन गुगली के लिए: यह बहुत अच्छा है अगर आपको एक सीएसपी (सामग्री सुरक्षा नीति) के आसपास काम करने की आवश्यकता है। हम बहुत सी लिपियों का उपयोग करते हैं जिसमें हम भाषा संसाधनों और एपीआई कुंजियों आदि से निर्धारित स्ट्रिंग्स को जेएस फाइलों में पास करते हैं।
मंकीसेनकोडेडो

2
ध्यान दें कि आप भी उपयोग कर सकते हैं document.currentScript, संगतता के लिए caniuse.com/#feat=document-currentscript देखें (या पॉलीफ़िल का उपयोग करें)
Yves M.

$(..)वाक्य रचना jQuery है, मत भूलना इसे शामिल करने की।
तिमु

48

एक और विचार जो मुझे आया था idवह <script>तत्व को बता रहा था और data-*विशेषताओं के रूप में तर्कों को पारित करना था । परिणामी <script>टैग कुछ इस तरह दिखाई देगा:

<script id="helper" data-name="helper" src="helper.js"></script>

स्क्रिप्ट तब आईडी का उपयोग प्रोग्रामेटिक रूप से खुद को खोजने और तर्कों को पार्स करने के लिए कर सकती है। पिछले <script>टैग को देखते हुए , नाम को इस तरह से पुनः प्राप्त किया जा सकता है:

var name = document.getElementById("helper").getAttribute("data-name");

हम name=helper


4
यदि आप आईडी विशेषता पर निर्भर नहीं होना चाहते हैं, तो आप पेज पर helper.jsसभी scriptटैग के माध्यम से अपना स्क्रिप्ट लूप भी बना सकते हैं, जिसके साथ आप देख सकते हैं scr="helper.js"और फिर निकाल सकते हैं data-name
jvannistelrooy

1
@jvannistelrooy मैंने कोशिश नहीं की है, लेकिन मेरा मानना ​​है कि एक को jquery और एक चतुर चयनकर्ता के माध्यम से स्क्रिप्ट प्राप्त करने में सक्षम होना चाहिए: var this_js_script = $('script[src*=somefile]');( ऊपर से कॉपी की गई )
लॉसमनोस

19

इस URL को देखें। यह आवश्यकता के लिए पूरी तरह से काम कर रहा है।

http://feather.elektrum.org/book/src.html

लेखक को बहुत धन्यवाद। त्वरित संदर्भ के लिए मैंने नीचे मुख्य तर्क दिया:

var scripts = document.getElementsByTagName('script');
var myScript = scripts[ scripts.length - 1 ];

var queryString = myScript.src.replace(/^[^\?]+\??/,'');

var params = parseQuery( queryString );

function parseQuery ( query ) {
  var Params = new Object ();
  if ( ! query ) return Params; // return empty object
  var Pairs = query.split(/[;&]/);
  for ( var i = 0; i < Pairs.length; i++ ) {
    var KeyVal = Pairs[i].split('=');
    if ( ! KeyVal || KeyVal.length != 2 ) continue;
    var key = unescape( KeyVal[0] );
    var val = unescape( KeyVal[1] );
    val = val.replace(/\+/g, ' ');
    Params[key] = val;
  }
  return Params;
}

1
मुझे यह समाधान पसंद आया, लेकिन इसे खंड पहचानकर्ता का उपयोग करने के लिए इसे थोड़ा संशोधित किया गया, ताकि यह कैश का भंडाफोड़ न करे: var frag = myScript.src.replace (/ ^ [^ \ #] + \ #? /, '') ;
मार्क नॉटिंघम

ओह, और मैंने पाया कि JSON को वहाँ काम करता है, जब तक आप इसे urlencode करते हैं।
मार्क नॉटिंघम

@ user378221 - क्या आपको यकीन है कि यह हमेशा सही फ़ाइल मिलेगी? मेरा मतलब है कि यह मानता है कि यह फ़ाइल अंतिम है। क्या होगा अगर इस निष्पादित होने से पहले अधिक स्क्रिप्ट टैग लोड किए गए हैं? मुझे नहीं पता कि क्या यह संभव है, लेकिन मुझे लगता है कि दस्तावेज़ अन्य टैग लोड करने के लिए कोड निष्पादन के लिए इंतजार नहीं करता है?
डेरियस। वी।

उपयोग करने के लिए बेहतर है डिकोड्यूरि का उपयोग करें () या डिकोड्यूरिकोम्पोनेंट () के बजाय यूनेस्केप को उस फ़ंक्शन के रूप में दर्शाया गया है।
स्टीव चिल्ड्स

@ Darius.V यह गैर- async स्क्रिप्ट के लिए काम करता है। मैं एक विकल्प के रूप में विकल्प 5 के साथ एक कमबैक का उपयोग करना पसंद करता हूं ।
ल्यूक

14

आप वैश्विक चर का उपयोग करते हैं:

ऐशे ही:

<script type="text/javascript">
   var obj1 = "somevalue";
   var obj2 = "someothervalue";
</script>
<script type="text/javascript" src="file.js"></script">

'File.js' में जावास्क्रिप्ट कोड तक पहुँच सकते हैं obj1औरobj2 समस्या के बिना।

EDIT बस यह जोड़ना चाहती है कि यदि 'file.js' जाँचना चाहता है कि क्या obj1और obj2यहाँ तक कि घोषित किया गया है कि आप निम्न फ़ंक्शन का उपयोग कर सकते हैं।

function IsDefined($Name) {
    return (window[$Name] != undefined);
}

उम्मीद है की यह मदद करेगा।


यह IE में एक अपरिचित त्रुटि फेंक देगा। उस फ़ंक्शन का पसंदीदा निकाय है return typeof window[$Name] !== 'undefined';। कृपया ध्यान दें कि आप उस फ़ंक्शन को चर के नाम से युक्त एक स्ट्रिंग पास करेंगे। यदि कॉलिंग कोड में चर मौजूद है (तो इसे फ़ंक्शन के रूप में लागू नहीं किया जा सकता है) के माध्यम से जांचना आसान है if (typeof var !== 'undefined')
एंथनी दीसांती

2
ओह, कभी IE का उपयोग करें। माफ़ करना।
नावामन

हां, लेकिन जावास्क्रिप्ट के साथ अपने अनुभव के अनुसार, मैं केवल मॉड्यूल नेमस्पेस के लिए वैश्विक चर का उपयोग करूंगा और जितना आवश्यक हो उतना ही बेनकाब करूंगा (जैसे init कोड, कुछ गुण), जैसा कि यहां दिखाया गया है । जटिल परियोजनाओं में नामकरण संघर्ष प्राप्त करना बहुत आसान है ... अपने समय के घंटे खर्च करना और फिर यह पता लगाना कि आपने पहले ही परियोजना में कहीं और चर का उपयोग किया है।
मैट

आप छोड़ सकते हैं var
तिमु

12

यहाँ अवधारणा का एक बहुत ही प्रचलित प्रमाण है।

मुझे यकीन है कि कम से कम 2 जगह हैं जहां सुधार हो सकता है, और मुझे यह भी यकीन है कि यह लंबे समय तक जीवित नहीं रहेगा। इसे और अधिक प्रस्तुत करने योग्य या उपयोगी बनाने के लिए किसी भी प्रतिक्रिया का स्वागत है।

कुंजी आपके स्क्रिप्ट तत्व के लिए एक आईडी सेट कर रही है। एकमात्र पकड़ यह है कि इसका मतलब यह है कि आप स्क्रिप्ट को केवल एक बार कॉल कर सकते हैं क्योंकि यह क्वेरी स्ट्रिंग को खींचने के लिए उस आईडी की तलाश करता है। यह तय किया जा सकता है, अगर, इसके बजाय, स्क्रिप्ट सभी क्वेरी तत्वों के माध्यम से यह देखने के लिए है कि उनमें से कोई भी इसे इंगित करता है, और यदि ऐसा है, तो ऐसे स्क्रिप्ट तत्व के अंतिम उदाहरण का उपयोग करता है। वैसे भी, कोड के साथ:

स्क्रिप्ट कहा जा रहा है:

window.onload = function() {
//Notice that both possible parameters are pre-defined.
//Which is probably not required if using proper object notation
//in query string, or if variable-variables are possible in js.
var header;
var text;

//script gets the src attribute based on ID of page's script element:
var requestURL = document.getElementById("myScript").getAttribute("src");

//next use substring() to get querystring part of src
var queryString = requestURL.substring(requestURL.indexOf("?") + 1, requestURL.length);

//Next split the querystring into array
var params = queryString.split("&");

//Next loop through params
for(var i = 0; i < params.length; i++){
 var name  = params[i].substring(0,params[i].indexOf("="));
 var value = params[i].substring(params[i].indexOf("=") + 1, params[i].length);

    //Test if value is a number. If not, wrap value with quotes:
    if(isNaN(parseInt(value))) {
  params[i] = params[i].replace(value, "'" + value + "'");
 }

    // Finally, use eval to set values of pre-defined variables:
 eval(params[i]);
}

//Output to test that it worked:
document.getElementById("docTitle").innerHTML = header;
document.getElementById("docText").innerHTML = text;
};

स्क्रिप्ट निम्नलिखित पेज के माध्यम से बुलाया:

<script id="myScript" type="text/javascript" 
        src="test.js?header=Test Page&text=This Works"></script>

<h1 id="docTitle"></h1>
<p id="docText"></p>

इसलिए eval वास्तव में वैश्विक चर के रूप में मूल्य निर्धारित करेगा ... बहुत अच्छा।
रोज़मजई

1
ईविल बुराई से दूर है
बैरी चैपमैन

@barrychapman - ओह यार, 2010. मुझे आश्चर्य है कि वहां 10 अन्य लाल झंडे नहीं थे।
एंथनी

9

बहुत सरल हो सकता है

उदाहरण के लिए

<script src="js/myscript.js?id=123"></script>
<script>
    var queryString = $("script[src*='js/myscript.js']").attr('src').split('?')[1];
</script>

फिर आप क्वेरी स्ट्रिंग को नीचे जैसे json में बदल सकते हैं

var json = $.parseJSON('{"' 
            + queryString.replace(/&/g, '","').replace(/=/g, '":"') 
            + '"}');

और फिर उपयोग कर सकते हैं

console.log(json.id);

6

यह आसानी से किया जा सकता है यदि आप jQuery जैसे कुछ जावास्क्रिप्ट फ्रेमवर्क का उपयोग कर रहे हैं। इस तरह,

var x = $('script:first').attr('src'); //Fetch the source in the first script tag
var params = x.split('?')[1]; //Get the params

अब आप इन पैरामेट्स को अपने परिवर्तनीय मापदंडों के रूप में विभाजित करके उपयोग कर सकते हैं।

एक ही प्रक्रिया को किसी भी ढांचे के बिना किया जा सकता है, लेकिन कोड की कुछ और लाइनें ले जाएगा।


2
एक jQuery प्लगइन भी है जिसे parseQuery कहा जाता है जो इसे और भी आसान बनाता है: plugins.jquery.com/project/parseQuery
जिमी

@JimmyCuadra - दुर्भाग्य से, आपके द्वारा प्रदान किया गया लिंक टूट गया है। लेकिन मुझे खुद jQuery में एक समान दृष्टिकोण मिला: jQuery.param ()
मैट

1

खैर, आपके पास किसी भी स्क्रिप्टिंग भाषा द्वारा बनाई जा रही जावास्क्रिप्ट फाइल हो सकती है, जो आपके चर को हर अनुरोध पर फ़ाइल में इंजेक्ट करती है। आपको अपने वेबसर्वर को कहना होगा कि वह js- फाइलों को स्टैटिकली डिसाइड न करें (mod_rewrite पर्याप्त होगा)।

हालांकि जागरूक रहें कि आप इन js-files के किसी भी कैशिंग को खो देते हैं क्योंकि उन्हें लगातार बदल दिया जाता है।

अलविदा।


1
समझ में नहीं आता है कि यह क्यों अस्वीकृत किया गया था। यह सर्वर साइड लॉजिक का सहारा लेते हुए पूरी तरह से वैध समाधान है। जहां तक ​​मैं देखता हूं, ओपी को पूरी तरह से जावास्क्रिप्ट समाधान होने की आवश्यकता नहीं है।
अनॉयज 17

@aefxx - आप सही हैं। <script>ब्लॉक के अंदर आप कुछ का उपयोग कर सकते हैं जैसे MyModule.Initialize( '<%: Model.SomeProperty%>', '<%: Model.SomeOtherProperty%>', ...);कि सर्वर पर प्रदान किया गया है। सावधानी: <%:मूल्य से बच जाता है, जबकि <%=मान को बिना बदले भेजा जाता है। MyModuleएक नेमस्पेस होगा (यानी .js फ़ाइल के अंदर एक वैरिएबल जो कि सेल्फ इनवैलिड हो, जो फंक्शन को उजागर करता है Initialize)। मैंने आपके उत्तर को गलत ठहराया, क्योंकि यह एक सहायक योगदान है।
मैट

नोट: अवधारणा, कैसे एक मॉड्यूल बनाने के लिए जिसमें एक उजागर संपत्ति होती है, इस पृष्ठ पर यहां और अधिक विवरण में वर्णित है ।
मैट

1

अच्छा सवाल और रचनात्मक जवाब लेकिन मेरा सुगमता आपके तरीकों को पैरामेट्रीकृत करना है और यह आपकी सभी समस्याओं को बिना किसी चाल के हल करना चाहिए।

यदि आपके पास कार्य है:

function A()
{
    var val = external_value_from_query_string_or_global_param;
}

आप इसे बदल सकते हैं:

function B(function_param)
{
    var val = function_param;
}

मुझे लगता है कि यह सबसे प्राकृतिक दृष्टिकोण है, आपको 'फ़ाइल मापदंडों' के बारे में अतिरिक्त प्रलेखन की आवश्यकता नहीं है और आप इसे प्राप्त करते हैं। यह विशेष रूप से उपयोगी है यदि आप अन्य डेवलपर्स को अपनी js फ़ाइल का उपयोग करने की अनुमति देते हैं।


0

नहीं, आप वास्तव में JS फ़ाइल URL के क्वेरिस्ट्रिंग भाग में चर जोड़कर ऐसा नहीं कर सकते। यदि इसका कोड लिखने के हिस्से को स्ट्रिंग को पार्स करने के लिए जो आपको परेशान करता है, तो शायद एक और तरीका होगा कि आप अपने वैरिएबल को एनकोड करें और उन्हें टैग की rel विशेषता जैसी किसी चीज़ में डालें? मुझे नहीं पता कि HTML सत्यापन के संदर्भ में यह कितना वैध है, यदि ऐसा कुछ है जिसके बारे में आप बहुत चिंतित हैं। तो फिर तुम सिर्फ स्क्रिप्ट की rel विशेषता खोजने की जरूरत है और फिर json_decode कि।

जैसे

<script type='text/javascript' src='file.js' rel='{"myvar":"somevalue","anothervar":"anothervalue"}'></script>

2
आप इसे नकली क्लेरिस्ट्रिंग के साथ कर सकते हैं। यह सिर्फ एक अच्छा विचार नहीं है। लेकिन न तो यह है। रिले विशेषता एक प्रकार के लिंक संबंध को निर्दिष्ट करने के लिए है, स्क्रिप्ट टैग में यादृच्छिक डेटा को रटना नहीं।
मैथ्यू फ्लैशेन

1
^ ^ सहमत हुए। मैं इसे छोड़ने के साथ कोई समस्या नहीं देख सकता, और <script> var obj1 = "somevalue" </ script> दृष्टिकोण का उपयोग करके, इसका सबसे अच्छा तरीका है, और मुझे विश्वास है - सही तरीका।
दाल हुंदल

0

यह मान्य HTML नहीं है (मुझे नहीं लगता) लेकिन यह काम करता है अगर आप अपने वेबपेज में स्क्रिप्ट टैग के लिए एक कस्टम विशेषता बनाते हैं :

<script id="myScript" myCustomAttribute="some value" ....>

फिर जावास्क्रिप्ट में कस्टम विशेषता का उपयोग करें:

var myVar = document.getElementById( "myScript" ).getAttribute( "myCustomAttribute" );

सुनिश्चित नहीं है कि यह स्क्रिप्ट स्रोत स्ट्रिंग को पार्स करने से बेहतर या खराब है।


0

यदि आपको एक ऐसा तरीका चाहिए जो CSP चेक को पास करे (जो असुरक्षित-इनलाइन को प्रतिबंधित करता है) तो आपको स्क्रिप्ट और CSP निर्देश दोनों के लिए एक अद्वितीय मान जोड़ने के लिए गैर-विधि का उपयोग करना होगा या अपने मूल्यों को html में लिखना होगा और उन्हें फिर से पढ़ना होगा।

एक्सप्रेस के लिए गैर विधि। जेएस:

const uuidv4 = require('uuid/v4')

app.use(function (req, res, next) {
  res.locals.nonce = uuidv4()
  next()
})

app.use(csp({
  directives: {
    scriptSrc: [
      "'self'",
      (req, res) => `'nonce-${res.locals.nonce}'`  // 'nonce-614d9122-d5b0-4760-aecf-3a5d17cf0ac9'
    ]
  }
}))

app.use(function (req, res) {
  res.end(`<script nonce="${res.locals.nonce}">alert(1 + 1);</script>`)
})

या HTML विधि के लिए मान लिखें। इस मामले में Jquery का उपयोग कर:

<div id="account" data-email="{{user.email}}"></div>
...


$(document).ready(() => {
    globalThis.EMAIL = $('#account').data('email');
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.