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

IT技术 javascript
2021-01-30 20:22:21

我将 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 ”。

6个回答

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

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

该变量myScript现在具有脚本 dom 元素。您可以使用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; };
})();
好的...我的问题就变成了,在移动到下一个脚本标签之前,所有浏览器是否总是完全加载并执行远程脚本的完整内容?这标准化有多严格?我可以想象它同时发生......
2021-03-18 20:22:21
但是,在所有浏览器中,这是否总是返回正确脚本的 URL?看起来它会返回最后一个脚本标签,但是如果文档中包含多个脚本标签怎么办?
2021-03-21 20:22:21
因为如果脚本标签包含 document.write 会发生什么,所以要求脚本完全有序地运行。这就是建议将脚本放在页面底部的原因,因为它们实际上会阻止加载其他内容。也就是说,HTML5 使用 async 和 defer 属性修改了它:whatwg.org/specs/web-apps/current-work/multipage/...
2021-03-27 20:22:21
我遇到过这种算法不能可靠工作的情况。设置为 async 的其他脚本标记可以在您的脚本被请求和运行之间运行。这些脚本可以将其他脚本添加到出现在您的 DOM 之后的 DOM 中。当您的脚本运行时,页面上的最后一个脚本不再是您的脚本,并且src返回错误
2021-03-27 20:22:21
如果在页面加载后使用以下内容加载脚本,这将不起作用: document.getElementsByTagName("head")[0].appendChild(scriptElement);
2021-04-11 20:22:21

您可以将 id 属性添加到您的脚本标签(即使它在 head 标签内):

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

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

document.getElementById("myscripttag").src

当然,包含您的脚本的每个文档的 id 值都应该相同,但我认为这不会给您带来很大的不便。

此答案应标记为“已接受”,因为它涵盖了您不在“全局”脚本上下文或“异步”脚本中调用方法的情况,并且它不依赖于浏览器实现。
2021-03-30 20:22:21
请注意.src,即使指定了相对路径,也可以返回绝对路径。您可以使用.getAttribute('src')
2021-04-12 20:22:21

除了 IE 支持的所有东西

document.currentScript
更准确地说:document.currentScript.src
2021-03-13 20:22:21
一个警告!如果加载的脚本类型是module,它将不起作用。更多信息stackoverflow.com/questions/2976651/...
2021-04-02 20:22:21

简单明了的解决方案,效果很好:

如果不是 IE 你可以使用document.currentScript
For IE 你可以这样document.querySelector('script[src*="myscript.js"]')
做:

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

在module脚本中,您可以使用:

 import.meta.url

mdn 中所述

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

我有一些与我的脚本相关的模板文件,所以我没有对它们进行硬编码,而是创建了类来自动创建路径。完整的源代码在 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('.');
  };
}
在这里聚会有点晚了,但我正在尝试这个代码片段,发现它在 for 循环中将 2 添加到当前索引的部分“callerIndex = Number(i) + 2;” 似乎 break 是不必要的,并导致它无法工作。简单地消除“+ 2”就可以了。有什么我误解或其他一些需要 + 2 的情况吗?
2021-03-18 20:22:21
你不需要以这种方式抛出“错误”(得到它的“.stack”)它只是一个像其他人一样的对象:console.log(new Error().stack);
2021-03-28 20:22:21
感谢这个想法,并感谢@AbdullahAydın 防止投掷的想法。那么我猜下面的单线可以解决问题,不是吗?var scriptUrl = new Error().stack.match(/@(https?:\/\/.+):\d+:\d+/)[1]
2021-03-30 20:22:21
另外@Pierre-Antoine 请记住 Error.prototype.stack 属性是非标准的:/您应该小心使用它。developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
2021-04-08 20:22:21
@AbdullahAydın:请注意,在抛出错误之前,不会在 IE 和 Edge 浏览器中填充新错误的堆栈属性
2021-04-10 20:22:21