如何获取当前正在执行的 javascript 代码的文件路径

发布于 2024-08-21 03:08:38 字数 406 浏览 12 评论 0原文

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

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

抱歉,如果措辞有点令人困惑。

I'm trying to do something like a C #include "filename.c", or PHP include(dirname(__FILE__)."filename.php") but in javascript. I know I can do this if I can get the URL a js file was loaded from (e.g. the URL given in the src attribute of the tag). Is there any way for the javascript to know that?

Alternatively, is there any good way to load javascript dynamically from the same domain (without knowing the domain specifically)? For example, lets say we have two identical servers (QA and production) but they clearly have different URL domains. Is there a way to do something like include("myLib.js"); where myLib.js will load from the domain of the file loading it?

Sorry if thats worded a little confusingly.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(13

南汐寒笙箫 2024-08-28 03:08:38

在脚本内:

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

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

(function() { ... })();

Within the script:

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

This works because the browser loads and executes scripts in order, so while your script is executing, the document it was included in is sure to have your script element as the last one on the page. This code of course must be 'global' to the script, so save src somewhere where you can use it later. Avoid leaking global variables by wrapping it in:

(function() { ... })();
尐籹人 2024-08-28 03:08:38

除 Internet Explorer(任何版本)之外的所有浏览器都有 文档。 currentScript,它始终有效(无论文件是如何包含的(异步、小书签等))。

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

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

Tadaa。

All browsers except Internet Explorer (any version) have document.currentScript, which always works always (no matter how the file was included (async, bookmarklet etc)).

If you want to know the full URL of the JS file you're in right now:

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

Tadaa.

爱你是孤单的心事 2024-08-28 03:08:38

我刚刚做了这个小把戏:

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

screenshot

适用于:Chrome、Firefox、Edge、Opera

尽情享受!

I just made this little trick :

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

screenshot

Works on: Chrome, Firefox, Edge, Opera

Enjoy !

和我恋爱吧 2024-08-28 03:08:38

如果您的文档中有内联脚本,则此处接受的答案不起作用。为了避免这种情况,您可以使用以下命令仅定位具有 [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 模板遇到的一些问题。

The accepted answer here does not work if you have inline scripts in your document. To avoid this you can use the following to only target <script> tags with a [src] attribute.

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

This effectively captures the last external .js file, solving some issues I encountered with inline JS templates.

挽容 2024-08-28 03:08:38

根据此处找到的答案,我得出以下结论:

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 捆绑。

Refining upon the answers found here I came up with the following:

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;

BTW: I'm using CommonJS
module format and bundling with webpack.

路还长,别太狂 2024-08-28 03:08:38

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

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

info = stackinfo()
console.log('This is the url of the script '+info[0].file)

I've more recently found a much cleaner approach to this, which can be executed at any time, rather than being forced to do it synchronously when the script loads.

Use stackinfo to get a stacktrace at a current location, and grab the info.file name off the top of the stack.

info = stackinfo()
console.log('This is the url of the script '+info[0].file)
过去的过去 2024-08-28 03:08:38

我编写了一个简单的函数,它允许使用 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;
    }

};

您可以在此处查看它。

I've coded a simple function which allows to get the absolute location of the current javascript file, by using a try/catch method.

// 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;
    }

};

You can see it here.

自演自醉 2024-08-28 03:08:38

完善此处找到的答案:

小技巧

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

Refining upon the answers found here:

little trick

getCurrentScript and getCurrentScriptPath

I came up with the following:

//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()})

靑春怀旧 2024-08-28 03:08:38

无论它是脚本、html 文件(例如框架)、css 文件、图像还是其他任何文件,如果您指定服务器/域,则 html 文档的路径将是默认,因此您可以执行以下操作,例如

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

Regardless of whether its a script, a html file (for a frame, for example), css file, image, whatever, if you dont specify a server/domain the path of the html doc will be the default, so you could do, for example,

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

or

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

If you don't provide the server/domain, the path will be relative to either the path of the page or script of the main document's path

与之呼应 2024-08-28 03:08:38

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

<script language="javascript" src="js/myLib.js" />

I may be misunderstanding your question but it seems you should just be able to use a relative path as long as the production and development servers use the same path structure.

<script language="javascript" src="js/myLib.js" />
夜无邪 2024-08-28 03:08:38

我整理了一些意大利面条代码,这些代码将使当前的 .js 文件运行(例如,如果您使用“node”运行脚本。您可以使用它来获取正在运行的脚本的目录)

这将其获取为“file” ://path/to/directoryWhere/fileExists"

var thisFilesDirectoryPath = stackinfo()[0].traceline.substring("readFile (".length, stackinfo()[0].traceline.length - ")".length-"readFile (".length);

这需要一个 npm 包(我确信它也在其他平台上):

npm i stackinfo

import stackinfo from 'stackinfo';var {stackinfo} = require("stackinfo");

I've thrown together some spaghetti code that will get the current .js file ran (ex. if you run a script with "node ." you can use this to get the directory of the script that's running)

this gets it as "file://path/to/directoryWhere/fileExists"

var thisFilesDirectoryPath = stackinfo()[0].traceline.substring("readFile (".length, stackinfo()[0].traceline.length - ")".length-"readFile (".length);

this requires an npm package (im sure its on other platforms as well):

npm i stackinfo

import stackinfo from 'stackinfo'; or var {stackinfo} = require("stackinfo");

随风而去 2024-08-28 03:08:38
function getCurrnetScriptName() {
    const url = new URL(document.currentScript.src);
    const {length:len, [len-1]:last} = url.pathname.split('/');
    return last.slice(0,-3);
}
function getCurrnetScriptName() {
    const url = new URL(document.currentScript.src);
    const {length:len, [len-1]:last} = url.pathname.split('/');
    return last.slice(0,-3);
}
月下伊人醉 2024-08-28 03:08:38

在 ES6 模块环境中,当前正在执行的模块的 URL 可以从 'import.meta' 属性获取。请参阅 MDN 文档

另请参阅 document.currentScript is null (Don Park 的回答)

一个示例:

//generalTests.mjs
getLocation();
function getLocation(){

    console.log("Current script location --->>> "+import.meta.url);

}

下面是 在模块环境中使用,该模块正在 HTML 脚本元素中加载

<body>
    <script type="module" src="generalTests.mjs"></script>
</body>

控制台输出如下:
控制台输出

In an ES6 module environment, the URL of the currently executing module can be obtained from 'import.meta' property. Refer MDN Document.

Also refer document.currentScript is null (Don Park's answer)

Below is an example:

//generalTests.mjs
getLocation();
function getLocation(){

    console.log("Current script location --->>> "+import.meta.url);

}

The above is being used in a module environment, where the module is being loaded in HTML script element

<body>
    <script type="module" src="generalTests.mjs"></script>
</body>

The console output is as follows:
console output

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文