我的脚本源 URL 是什么?

IT技术 javascript dom absolute-path src
2021-02-05 15:33:27

是否有一种简单可靠的方法来确定当前正在执行的 JavaScript 文件(在网页内)的 URL?

我对此唯一的想法是扫描 DOM 中的所有脚本src属性以查找当前文件的引用方式,然后通过将其应用于document.location. 任何人都有其他想法,是否有一些我完全忽略的超级简单方法?

更新:通过 DOM 访问的脚本元素已经有一个src包含完整 URL属性。我不知道那是多么普遍/标准,但是您可以使用getAttribute("src")which 将返回 [X]HTML 中的任何原始属性值。

6个回答

把它放在需要知道它自己的url的js文件中。

完全合格(例如http://www.example.com/js/main.js):

var scriptSource = (function(scripts) {
    var scripts = document.getElementsByTagName('script'),
        script = scripts[scripts.length - 1];

    if (script.getAttribute.length !== undefined) {
        return script.src
    }

    return script.getAttribute('src', -1)
}());

或者 正如它在源代码中出现的那样(例如/js/main.js):

var scriptSource = (function() {
    var scripts = document.getElementsByTagName('script'),
        script = scripts[scripts.length - 1];

    if (script.getAttribute.length !== undefined) {
        return script.getAttribute('src')
    }

    return script.getAttribute('src', 2)
}());

请参阅http://www.glennjones.net/Post/809/getAttributehrefbug.htm以了解getAttribute所使用参数的说明(这是一个 IE 错误)。

对于完全合格的人,您不能只使用 script.src 吗?你为什么使用 script.getAttribute('src', -1)???
2021-03-13 15:33:27
我遇到过这种算法不能可靠工作的情况。设置为 async 的其他脚本标记可以在您的脚本被请求和运行之间运行。这些脚本可以将其他脚本添加到出现在您的 DOM 之后的 DOM 中。当您的脚本运行时,页面上的最后一个脚本不再是您的脚本,并且src返回错误
2021-04-01 15:33:27
很好的答案。一个警告 - 如果脚本是延迟加载的(由另一个脚本注入到 DOM 中),它不会是 DOM 中的最后一个脚本,所以这个确切的片段将不起作用。
2021-04-02 15:33:27
肯定不能使用<script src="..." async>标签(延迟加载的 html5 形式),即使没有这些,它在 FF12 上也根本不起作用,所以我想最近的浏览器开始故意破坏它
2021-04-03 15:33:27
不是“应该打破”,而是“正在打破”我看到了这种情况。如果 javascripts 默认异步加载,页面看起来会更快。它可能会破坏功能,是的,但在大多数情况下它可能不会并且这些竞争条件可以并且由最新的 js 引擎加载时被识别和处理@MarcoDemaio
2021-04-05 15:33:27

对于最近的浏览器,您可以使用 document.currentScript 来获取此信息。

var mySource = document.currentScript.src;

好处是它对于异步加载的脚本更可靠。缺点是,据我所知,它没有得到普遍支持。它应该适用于 Chrome >= 29、FireFox >= 4、Opera >= 16。像许多有用的东西一样,它似乎不适用于 IE。

当我需要获取脚本路径时,我会检查是否定义了 document.currentScript,如果没有,则使用已接受的答案中描述的方法。

if (document.currentScript) {
    mySource = document.currentScript.src;
} else {
    // code omitted for brevity
}

https://developer.mozilla.org/en-US/docs/Web/API/document.currentScript

什么时候可以在 Chrome 中使用?它在 87 中还没有......?
2021-03-19 15:33:27
caniuse.com尚未监控此功能。您可以在此处帮助投票github.com/Fyrd/caniuse/issues/1099
2021-03-23 15:33:27
@Stephan 成功了! caniuse.com/#search=currentscript
2021-03-30 15:33:27

正如它在源代码中出现的那样(例如/js/main.js),这是跨浏览器的

var scriptSource = (function() 
{ 
    var scripts = document.getElementsByTagName('script'), 
        script = scripts[scripts.length - 1]; 

    //No need to perform the same test we do for the Fully Qualified
    return script.getAttribute('src', 2); //this works in all browser even in FF/Chrome/Safari
}()); 

完全合格(例如http://www.example.com/js/main.js):

经过一些测试,似乎很难以跨浏览器的方式获得完全合格的测试Crescent Fresh 建议 解决方案在 IE8 中不起作用以获得完全合格的,即使它在 IE7 中有效

此方法适用于延迟、异步和延迟加载 因为您知道脚本的文件名,以及它是否是唯一的

/* see  
 * http://stackoverflow.com/questions/984510/what-is-my-script-src-url/984656#984656
 * http://www.glennjones.net/Post/809/getAttributehrefbug.htm
 * 
 * iterate all script to find script with right filename
 * this work with async and defer (but your script MUST have a unique filemane)
 * mozilla support document.currentScript and we use it, if is set
 *
 * this will not work with local script loaded by jQuery.getScript(),
 * since there is no script tag added into the dom. the script is only evaluated in global space.
 * http://api.jquery.com/jQuery.getScript/
 *  
 * to fix this odd, you can add a reference in meta ( meta[name=srcipt][content=url] )
 * when you load the script
 */
var scriptFilename = 'jquery.plugins.template.js'; // don't forget to set the filename 
var scriptUrl = (function() {
    if (document.currentScript) { // support defer & async (mozilla only)
        return document.currentScript.src;
    } else {
        var ls,s;
        var getSrc = function (ls, attr) {
            var i, l = ls.length, nf, s;
            for (i = 0; i < l; i++) {
                s = null;
                if (ls[i].getAttribute.length !== undefined) { 
                    s = ls[i].getAttribute(attr, 2);                    
                }               
                if (!s) continue; // tag with no src
                nf = s;
                nf = nf.split('?')[0].split('/').pop(); // get script filename
                if (nf === scriptFilename) {
                    return s;
                }
            }
        };          
        ls = document.getElementsByTagName('script');
        s = getSrc(ls, 'src');
        if ( !s ) { // search reference of script loaded by jQuery.getScript() in meta[name=srcipt][content=url]
            ls = document.getElementsByTagName('meta');             
            s = getSrc(ls, 'content');
        }           
        if ( s ) return s;
    }
    return '';
})();

var scriptPath =  scriptUrl.substring(0, scriptUrl.lastIndexOf('/'))+"/";

带有它的 jquery 插件模板:https : //github.com/mkdgs/mkdgs-snippet/blob/master/javascript/jquery.plugins.template.js

注意:这不适用于 jQuery.getScript() 加载的本地脚本,因为没有添加到 dom 中的脚本标记。该脚本仅在全局空间中进行评估。 http://api.jquery.com/jQuery.getScript/

要修复它,您可以执行以下操作:

function loadScript(url,callback) {     

    if ( $('[src="'+url+'"]').length ) return true; // is already loaded    

    // make a reference of the loaded script
    if ( $('meta[content="'+url+'"]', $("head")).length ) return true; // is already loaded 
    var meta = document.createElement('meta');
    meta.content = url;
    meta.name = 'script';
    $("head").append(meta);

    return $.ajax({
          cache: true,
          url: u,
          dataType: 'script',
          async: false,
          success : function (script) {                     
                try { 
                    if ( typeof callback == 'function' ) callback();    
                } catch (error) { 
                    //console.log(error);
                }
          }
     });
}
有趣的使用document.currentScripthere。可悲的是,浏览器支持信息不是关于TEY提供caniuse.com您可以通过对打开的问题进行投票来提供帮助:github.com/Fyrd/caniuse/issues/1099
2021-04-02 15:33:27
我投了赞成票,但 caniuse.com 不是唯一的信息来源。developer.mozilla.org/en-US/docs/Web/API/Document/currentScript
2021-04-05 15:33:27

如果这是一个严格的客户端解决方案,那么您的解决方案听起来不错。

如果您在服务器上编写代码,您可能只需使用脚本的完全解析 URL 填充一个 div/隐藏字段/(在此处插入您最喜欢的 HTML 元素),然后在客户端使用您的 javascript 获取它。

服务器端,他可以只通过 asp/php/jsp/cgi 为 js 提供服务,并从那里输出 javascript 中的 url。
2021-03-14 15:33:27
@ZJR——我目前正在享受“JS低谷”的想法,但是它已经提供了;)
2021-03-19 15:33:27