77

我正在尝试用 javascript 做类似 C#include "filename.c"或 PHP的事情include(dirname(__FILE__)."filename.php")。我知道如果我可以获取加载 js 文件的 URL(例如标签的 src 属性中给出的 URL),我可以做到这一点。javascript有什么办法知道吗?

或者,有没有什么好方法可以从同一个域动态加载 javascript(不知道具体的域)?例如,假设我们有两个相同的服务器(QA 和生产),但它们显然具有不同的 URL 域。有没有办法做类似include("myLib.js");myLib.js 将从加载它的文件的域加载的地方?

对不起,如果那措辞有点混乱。

4

11 回答 11

88

在脚本中:

var scripts = document.getElementsByTagName("script"),
    src = scripts[scripts.length-1].src;

这是因为浏览器按顺序加载和执行脚本,所以当你的脚本正在执行时,它所包含的文档肯定会将你的脚本元素作为页面上的最后一个元素。当然,这段代码对于脚本来说必须是“全局的”,所以请保存src在以后可以使用的地方。通过将全局变量包装在以下内容中来避免泄漏全局变量:

(function() { ... })();
于 2010-02-12T23:08:35.030 回答
63

除了 Internet Explorer(任何版本)之外的所有浏览器都有document.currentScript,它始终可以正常工作(无论文件如何包含(异步、书签等))。

如果你想知道你现在所在的 JS 文件的完整 URL:

var script = document.currentScript;
var fullUrl = script.src;

多达。

于 2013-10-25T12:09:52.703 回答
20

我刚刚做了这个小技巧:

window.getRunningScript = () => {
    return () => {      
        return new Error().stack.match(/([^ \n])*([a-z]*:\/\/\/?)*?[a-z0-9\/\\]*\.js/ig)[0]
    }
}
console.log('%c Currently running script:', 'color: blue', getRunningScript()())

截屏

适用于:Chrome、Firefox、Edge、Opera

享受 !

于 2017-03-04T10:23:51.947 回答
18

如果您的文档中有内联脚本,则此处接受的答案不起作用。为避免这种情况,您可以使用以下内容仅针对<script>具有[src]属性的标签。

/**
 * Current Script Path
 *
 * Get the dir path to the currently executing script file
 * which is always the last one in the scripts array with
 * an [src] attr
 */
var currentScriptPath = function () {

    var scripts = document.querySelectorAll( 'script[src]' );
    var currentScript = scripts[ scripts.length - 1 ].src;
    var currentScriptChunks = currentScript.split( '/' );
    var currentScriptFile = currentScriptChunks[ currentScriptChunks.length - 1 ];

    return currentScript.replace( currentScriptFile, '' );
}

这有效地捕获了最后一个外部 .js 文件,解决了我在使用内联 JS 模板时遇到的一些问题。

于 2014-09-24T17:40:23.817 回答
8

完善在这里找到的答案,我想出了以下内容:

getCurrentScript.js

var getCurrentScript = function() {
  if (document.currentScript) {
    return document.currentScript.src;
  } else {
    var scripts = document.getElementsByTagName('script');
    return scripts[scripts.length - 1].src;
  }
}

// module.exports = getCurrentScript;
console.log({log: getCurrentScript()})

getCurrentScriptPath.js

var getCurrentScript = require('./getCurrentScript');

var getCurrentScriptPath = function () {
  var script = getCurrentScript();
  var path = script.substring(0, script.lastIndexOf('/'));
  return path;
};

module.exports = getCurrentScriptPath;

顺便说一句:我正在使用CommonJS 模块格式并与webpack捆绑。

于 2014-12-09T01:25:13.577 回答
4

我最近发现了一种更简洁的方法,可以随时执行,而不是在脚本加载时被迫同步执行。

使用stackinfo在当前位置获取堆栈跟踪,并info.file从堆栈顶部获取名称。

info = stackinfo()
console.log('This is the url of the script '+info[0].file)
于 2014-05-05T00:28:42.767 回答
3

我编写了一个简单的函数,它允许通过使用 try/catch 方法获取当前 javascript 文件的绝对位置。

// Get script file location
// doesn't work for older browsers

var getScriptLocation = function() {
    var fileName    = "fileName";
    var stack       = "stack";
    var stackTrace  = "stacktrace";
    var loc     = null;

    var matcher = function(stack, matchedLoc) { return loc = matchedLoc; };

    try { 

        // Invalid code
        0();

    }  catch (ex) {

        if(fileName in ex) { // Firefox
            loc = ex[fileName];
        } else if(stackTrace in ex) { // Opera
            ex[stackTrace].replace(/called from line \d+, column \d+ in (.*):/gm, matcher);
        } else if(stack in ex) { // WebKit, Blink and IE10
            ex[stack].replace(/at.*?\(?(\S+):\d+:\d+\)?$/g, matcher);
        }

        return loc;
    }

};

你可以在这里看到它。

于 2014-10-11T21:35:17.960 回答
3

完善此处找到的答案:

小把戏

getCurrentScript 和 getCurrentScriptPath

我想出了以下内容:

//Thanks to https://stackoverflow.com/a/27369985/5175935
var getCurrentScript = function() {

  if (document.currentScript && (document.currentScript.src !== ''))
    return document.currentScript.src;
  var scripts = document.getElementsByTagName('script'),
    str = scripts[scripts.length - 1].src;
  if (str !== '')
    return str ;
  //Thanks to https://stackoverflow.com/a/42594856/5175935
  return new Error().stack.match(/(https?:[^:]*)/)[0];

};

//Thanks to https://stackoverflow.com/a/27369985/5175935
var getCurrentScriptPath = function() {
  var script = getCurrentScript(),
    path = script.substring(0, script.lastIndexOf('/'));
  return path;
};

console.log({path: getCurrentScriptPath()})

于 2020-03-01T01:20:55.437 回答
1

我可能误解了您的问题,但似乎只要生产和开发服务器使用相同的路径结构,您就应该能够使用相对路径。

<script language="javascript" src="js/myLib.js" />
于 2010-02-12T23:06:28.680 回答
1

无论它是脚本、html 文件(例如,用于框架)、css 文件、图像等等,如果您指定服务器/域,则 html 文档的路径将是默认路径,因此您可以这样做,例如,

<script type=text/javascript src='/dir/jsfile.js'></script>

或者

<script type=text/javascript src='../../scripts/jsfile.js'></script>

如果您不提供服务器/域,则路径将相对于页面路径或主文档路径的脚本

于 2010-02-12T23:06:49.400 回答
0
function getCurrnetScriptName() {
    const url = new URL(document.currentScript.src);
    const {length:len, [len-1]:last} = url.pathname.split('/');
    return last.slice(0,-3);
}
于 2021-06-03T09:12:12.070 回答