JavaScript-如何获取被调用脚本的URL?


81

我将myscript.js包含在这样的文件中http://site1.com/index.html

<script src=http://site2.com/myscript.js></script>

在“ myscript.js”中,我想访问URL“ http://site2.com/myscript.js ”。我想要这样的东西:

function getScriptURL() {
    // something here
    return s
}

alert(getScriptURL());

如果从上述index.html调用,它将警告“ http://site2.com/myscript.js ”。




根据您的示例网址,如果浏览器设置为阻止第三方脚本,则可能需要注意预期的行为。

Answers:


58

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

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

变量myScript现在具有脚本dom元素。您可以使用来获取src网址myScript.src

注意,这需要作为脚本初始评估的一部分执行。如果您不想污染Javascript名称空间,则可以执行以下操作:

var getScriptURL = (function() {
    var scripts = document.getElementsByTagName('script');
    var index = scripts.length - 1;
    var myScript = scripts[index];
    return function() { return myScript.src; };
})();

23
在所有浏览器中,这是否总是会返回正确脚本的URL?看起来它将返回最后一个脚本标签,但是如果文档中包含多个脚本标签,该怎么办?
MikeC8 2010年

3
好的...然后我的问题就变成了,所有浏览器在进入下一个脚本标签之前,是否始终会完全加载并执行远程脚本的全部内容?这个标准有多严格?我可以想象它是并行发生的……
MikeC8 2010年

1
由于脚本标记包含document.write会发生什么情况,因此脚本必须完整且按顺序运行。这就是建议将脚本放在页面底部的原因,因为它们实际上会阻止其他内容的加载。就是说,HTML5通过使用async和defer属性对其
6

9
如果在页面加载后使用如下所示的内容加载脚本,则此方法将document.getElementsByTagName("head")[0].appendChild(scriptElement);
无效

16
我遇到了这种算法无法可靠运行的情况。设置为异步的其他脚本标签可以在请求和运行的脚本之间运行。这些脚本可以将其他脚本添加到DOM之后出现的DOM中。当您的脚本运行时,该页面上的最后一个脚本不再是您的脚本,并且src会返回错误。
卡尔,

54

您可以将id属性添加到脚本标签中(即使它位于head标签中):

<script id="myscripttag" src="http://site2.com/myscript.js"></script>

然后按以下方式访问其src:

document.getElementById("myscripttag").src

当然,包含脚本的每个文档的id值都应该相同,但是我认为这对您来说不便。


1
此答案应标记为“已接受”,因为它涵盖了在非“全局”脚本上下文或“异步”脚本中调用方法时的情况,并且该方法不依赖于浏览器实现。
谢尔盖·科瓦连科

请注意.src,即使指定了相对路径,它也可以返回绝对路径。您可以使用.getAttribute('src')
ИльяЗеленько


18

我编写了一个类来查找与延迟加载和异步脚本标记一起使用的脚本的路径。

我有一些相对于我的脚本的模板文件,因此,我没有对它们进行硬编码,而是创建了创建类来自动创建路径。完整的源代码在github上。

不久前,我使用arguments.callee尝试执行类似的操作,但最近我在MDN上阅读到,严格模式下不允许使用

function ScriptPath() {
  var scriptPath = '';
  try {
    //Throw an error to generate a stack trace
    throw new Error();
  }
  catch(e) {
    //Split the stack trace into each line
    var stackLines = e.stack.split('\n');
    var callerIndex = 0;
    //Now walk though each line until we find a path reference
    for(var i in stackLines){
      if(!stackLines[i].match(/http[s]?:\/\//)) continue;
      //We skipped all the lines with out an http so we now have a script reference
      //This one is the class constructor, the next is the getScriptPath() call
      //The one after that is the user code requesting the path info (so offset by 2)
      callerIndex = Number(i) + 2;
      break;
    }
    //Now parse the string for each section we want to return
    pathParts = stackLines[callerIndex].match(/((http[s]?:\/\/.+\/)([^\/]+\.js)):/);
  }

  this.fullPath = function() {
    return pathParts[1];
  };

  this.path = function() {
    return pathParts[2];
  };

  this.file = function() {
    return pathParts[3];
  };

  this.fileNoExt = function() {
    var parts = this.file().split('.');
    parts.length = parts.length != 1 ? parts.length - 1 : 1;
    return parts.join('.');
  };
}

1
到这里参加聚会有点晚了,但是我正在尝试这段代码片段,发现它在for循环“ callerIndex = Number(i)+ 2;”中将当前索引加2的部分。似乎打破不必要,并导致其无法正常工作。简单地消除“ + 2”就可以了。是否有我误解的内容或某些其他情况需要+ 2?
Scott Smith

2
您无需以这种方式抛出“错误”(使其成为“ .stack”),它只是一个与其他对象一样的对象:console.log(new Error()。stack);
阿卜杜拉

1
感谢这个想法,也感谢@AbdullahAydın防止抛出的想法。然后我猜想下面的单线方法可以解决问题,不是吗?var scriptUrl = new Error()。stack.match(/ @(https?:\ / \ /.+):\ d +:\ d + /)[1]
Pierre-Antoine

1
另外@ Pierre-Antoine还要记住Error.prototype.stack属性是非标准的://您应该小心使用它。developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…–
阿卜杜拉

3
@AbdullahAydın:请注意,在引发错误之前,不会在IE和Edge浏览器中填充新错误的stack属性。
鲍勃·阿罗夫

15

如果您有机会使用jQuery,则代码如下所示:

$('script[src$="/myscript.js"]').attr('src');

它可以与延迟,异步和延迟加载脚本一起使用吗?
斯蒂芬

它只是在DOM中查找带有src“ /myscript.js”的脚本标签。其他属性无关紧要
Rebs

要将它与wordpress一起用于附加版本的其他任何地方,则应使用$('script [src * =“ / myscript.js”]')。attr('src'); 这样,它将在脚本末尾忽略?ver = 2.3.3。*将使它保持工作状态,无论结尾是什么。
Mav2287 '18

15

简单而直接的解决方案效果很好:

如果不是IE,则可以使用document.currentScript
IE document.querySelector('script[src*="myscript.js"]')

function getScriptURL(){
 var script =  document.currentScript || document.querySelector('script[src*="myscript.js"]')
 return script.src
}

2

以下代码可让您查找具有给定名称的脚本元素

var scripts = document.getElementsByTagName( 'script' );
        var len = scripts.length
        for(var i =0; i < len; i++) {
            if(scripts[i].src.search("<your JS file name") > 0 && scripts[i].src.lastIndexOf("/") >= 0) {
                absoluteAddr = scripts[i].src.substring(0, scripts[i].src.lastIndexOf("/") + 1);
                break;
            }
        }

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.