向 JavaScript 文件传递参数

通常我会有一个 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();

然后寻找我的价值观。

我想知道是否有另一种方法可以做到这一点,而不需要构建一个函数来解析我的字符串。

你们都知道其他方法吗?

290439 次浏览

使用全局变量: -D。

像这样:

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

Js 中的 JavaScript 代码可以毫无问题地访问 obj1obj2

只是想添加如果‘ file.js’想检查 obj1obj2是否已经声明,您可以使用以下函数。

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

希望这个能帮上忙。

如果你使用像 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 文件,在每次请求时将变量注入到文件中。您必须告诉您的 webserver 不要静态地输出 js-files (使用 mod _ rewrite 就足够了)。

但是要注意,这些 js-files 的缓存会随着它们的不断更改而丢失。

再见。

不,通过将变量添加到 JS 文件 URL 的 querystring 部分实际上不能做到这一点。如果它编写代码来解析困扰您的字符串,也许另一种方法是 json 编码您的变量,并将它们放在类似于标记的 rel 属性中?我不知道这在 HTML 验证方面是否有效,如果您非常担心这个问题的话。然后,您只需要找到脚本的 rel 属性,然后对其进行 json _ decode。

例句

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

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

这是一个非常匆忙的概念证明。

我相信至少有两个地方可以改进,我也相信这种植物在野外生存不了多久。欢迎提供任何反馈意见,使其更具体、更实用。

关键是为脚本元素设置 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>

看看这个 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;
}

很好的问题和创造性的答案,但我的建议是让你的方法参数化,这应该解决所有的问题没有任何技巧。

如果你有功能:

function A()
{
var val = external_value_from_query_string_or_global_param;
}

你可以把它改成:

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

我认为这是最自然的方法,您不需要创建关于“文件参数”的额外文档,您也会收到相同的文档。如果您允许其他开发人员使用您的 js 文件,那么这个特别有用。

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

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

在 somfile.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

等等。

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

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

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

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

不确定这比解析脚本源字符串好还是不好。

我遇到的另一个想法是为 <script>元素分配一个 id,并将参数作为 data-*属性传递。结果得到的 <script>标记如下:

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

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

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

我们得到 name = helper

可能很简单

比如说

<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, '":"')
+ '"}');

然后可以使用 like

console.log(json.id);

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

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

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

我偶然发现了这篇文章,希望找到一个比前一阵子写的更好的解决方案,希望能找到一个本地特性或类似的东西。< br/> 我将分享我的解决方案,直到一个更好的解决方案被实现。这在大多数现代浏览器上都可以使用,甚至在老版本的浏览器上也不需要尝试。译注: 上面的所有解决方案都是基于这样一个事实,即它必须注入预定义的、标记良好的 SCRIPT 标记,并且完全依赖于 HTML 实现。但是,如果脚本是动态注入的,或者更糟糕的是,如果您编写了一个库,将在各种网站上使用该库,该怎么办呢?< br/> 在这些情况和其他一些情况下,上述所有答案都是不充分的,甚至变得过于复杂

首先,让我们试着理解我们需要在这里实现什么。我们需要做的就是获取脚本本身的 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

这也适用于 需要和其他动态注入的文件脚本。

我认为在包含 javascript 的页面上使用 localStorage,然后在 javascript 本身内部重用它,这是更好更现代的解决方案。在 localStorage 中设置:

localStorage.setItem("nameOfVariable", "some text value");

并在 javascript 文件中引用它,比如:

localStorage.getItem("nameOfVariable");

在这里,我找到了另一种做同样事情的方法。在重复使用的 js 文件[ 正如我在测试中使用的那样,您可以使用 any. js 文件]中,我们将简单地列出所有脚本元素,并获得所需的脚本元素,因为它总是位于最后一个索引处。然后得到”。属性 src.value”。

现在,在任何脚本调用的情况下,它都是

<script src="./cttricks.js?data1=Hello&data2=World"></script>

在 cttrick. js 脚本文件中,

var scripts = document.getElementsByTagName('script');
var jsFile = new URL("http://" + scripts[scripts.length-1].attributes.src.value);
/*get value from query parameters*/
console.log(jsFile.searchParams.get("data1"));
console.log(jsFile.searchParams.get("data2"));

好好享受吧!

可以将参数传递给 js 模块,然后通过 import.meta.url读取它们。

例如,使用以下 HTML

<script type="module">
import './index.mjs?someURLInfo=5';
</script>

下面的 JavaScript 文件将记录 somURLInfo 参数:

// index.mjs
new URL(import.meta.url).searchParams.get('someURLInfo'); // 5

当一个文件导入另一个文件时也是如此:

// index.mjs
import './index2.mjs?someURLInfo=5';


// index2.mjs
new URL(import.meta.url).searchParams.get('someURLInfo'); // 5

HTML:

<script src='greet.js' data-param1='hello' data-param2='world'></script>

// greet.js:
const prm1=document.currentScript.dataset.param1;
const prm2=document.currentScript.dataset.param2;