将参数传递到JavaScript文件

2020/10/27 07:22 · javascript ·  · 0评论

通常,我会想要使用一个JavaScript文件,该文件要求在网页中定义某些变量。

所以代码是这样的:

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

然后搜索我的价值观。

我想知道是否还有另一种方法,而无需构建函数来解析我的字符串。

你们都知道其他方法吗?

如果可能,我建议不要使用全局变量。使用名称空间和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>

您可以传递具有任意属性的参数。在所有最近的浏览器中都可以使用。

<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

...等等...

我遇到的另一个想法是将an分配id<script>元素并将参数作为data-*属性传递结果<script>标签看起来像这样:

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

然后,脚本可以使用id以编程方式定位自身并解析参数。给定前面的<script>标签,可以像这样检索名称:

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

我们得到name=helper

检出此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;
}

您使用全局变量:-D。

像这样:

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

“ file.js”中的JavaScript代码可以访问obj1obj2没有问题。

编辑只是想补充一点,如果“file.js”想要检查obj1obj2甚至已经宣布你可以用下面的函数。

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

希望这可以帮助。

这是一个非常仓促的概念证明。

我敢肯定至少有2个地方可以改进,而且我也肯定这不会在野外长期存在。欢迎提供任何使它更美观或更有用的反馈。

关键是为脚本元素设置一个id。唯一的问题是,这意味着您只能调用一次脚本,因为它会寻找该ID来提取查询字符串。相反,如果脚本循环遍历所有查询元素以查看它们是否指向它,并且使用该脚本元素的最后一个实例,则可以修复此问题。无论如何,代码如下:

脚本被调用:

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>

可能很简单

例如

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

如果您使用的是jQuery之类的Javascript框架,则可以轻松完成此操作。像这样

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

现在,您可以通过拆分作为变量参数来使用这些参数。

无需任何框架即可完成相同的过程,但将花费更多的代码行。

好吧,您可以使用任何脚本语言来构建javascript文件,并在每次请求时将变量注入文件中。您必须告诉您的Web服务器不要静态地分发js文件(使用mod_rewrite就足够了)。

请注意,尽管这些js文件不断更改,但它们会丢失所有缓存。

再见

好的问题和有创意的答案,但是我的建议是使您的方法参数化,这应该可以解决所有问题而没有任何技巧。

如果您具有功能:

function A()
{
    var val = external_value_from_query_string_or_global_param;
}

您可以将其更改为:

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

我认为这是最自然的方法,您无需创建有关“文件参数”的额外文档,也可以收到相同的信息。如果您允许其他开发人员使用您的js文件,这将特别有用。

No, you cant really do this by adding variables to the querystring portion of the JS file URL. If its writing the portion of code to parse the string that bothers you, perhaps another way would be to json encode your variables and put them in something like the rel attribute of the tag? I don't know how valid this is in terms of HTML validation, if thats something you're very worried about. Then you just need to find the rel attribute of the script and then json_decode that.

eg

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

这不是有效的html(我不认为),但是如果您在网页中为script标签创建了自定义属性,它似乎可以工作

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

然后在javascript中访问自定义属性:

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

不知道这比解析脚本源字符串好还是坏。

如果需要通过CSP检查的方式(禁止不安全的内联),则必须使用nonce方法向脚本和CSP指令添加唯一值,或者将值写入html并再次读取它们。

express.js的Nonce方法:

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

尽管这个问题已经问了一段时间,但到今天仍然有用。这不是使用脚本文件参数的简单方法,但是我已经有了一些最适合这种方法的极端用例。

我碰到了这篇文章,以找到比我之前写的更好的解决方案,希望找到本机功能或类似功能。

我将分享我的解决方案,直到实施更好的解决方案为止。
这在大多数现代浏览器上都有效,甚至在较旧的浏览器上也没有尝试。

以上所有解决方案均基于以下事实,即必须注入预定义且标记明确的SCRIPT标签,并且完全依赖HTML实施。但是,如果脚本是动态注入的,或者更糟糕的是,如果您正在编写将在各种网站中使用的库,该怎么办?

在这些和其他情况下,以上所有答案都不足够,甚至变得太复杂。

首先,让我们尝试了解我们在这里需要实现的目标。我们需要做的就是获取脚本本身的URL,从那儿开始很轻松。

实际上,有一个很好的技巧可以从脚本本身获取脚本URL。本机Error的功能之一是能够提供“问题位置”的堆栈跟踪,包括到最后一次调用的确切文件跟踪。为了实现此目的,我将使用Error实例的stack属性,该属性一旦创建,便会给出完整的堆栈跟踪。

这是魔术的工作原理:

// The pattern to split each row in the stack trace string
const STACK_TRACE_SPLIT_PATTERN = /(?:Error)?\n(?:\s*at\s+)?/;
// For browsers, like Chrome, IE, Edge and more.
const STACK_TRACE_ROW_PATTERN1 = /^.+?\s\((.+?):\d+:\d+\)$/;
// For browsers, like Firefox, Safari, some variants of Chrome and maybe other browsers.
const STACK_TRACE_ROW_PATTERN2 = /^(?:.*?@)?(.*?):\d+(?::\d+)?$/;

const getFileParams = () => {
    const stack = new Error().stack;
    const row = stack.split(STACK_TRACE_SPLIT_PATTERN, 2)[1];
    const [, url] = row.match(STACK_TRACE_ROW_PATTERN1) || row.match(STACK_TRACE_ROW_PATTERN2) || [];
    if (!url) {
        console.warn("Something went wrong. You should debug it and find out why.");
        return;
    }
    try {
        const urlObj = new URL(url);
        return urlObj.searchParams; // This feature doesn't exists in IE, in this case you should use urlObj.search and handle the query parsing by yourself.
    } catch (e) {
        console.warn(`The URL '${url}' is not valid.`);
    }
}

现在,在任何脚本调用情况下,例如在OP情况下:

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

file.js脚本中,您现在可以执行以下操作:

const params = getFileParams();
console.log(params.get('obj2'));
// Prints: someothervalue

这也将与RequireJS和其他动态注入的文件脚本一起使用。

本文地址:http://javascript.askforanswer.com/jiangcanshuchuandidaojavascriptwenjian.html
文章标签: ,  
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!