获取当前执行的JavaScript代码的文件路径,用于动态加载跨域JavaScript文件。

5

我需要动态加载跨域JavaScript文件,以用于我的网站http://jsbookmarklets.com/中的书签。


解决方案应满足以下要求:

  • 获取当前文件路径
  • 当前网页和执行JS文件的域不同
  • 解决方案应跨浏览器使用
  • 可能会异步加载多个脚本(这就是为什么下面提到的相关问题不适用的原因)


我想要获取当前执行JavaScript代码的文件路径,以动态加载更多资源(如自定义代码、jQuery、jQuery UI和Ext JS库等CSS文件和JS文件),它们存储在与JavaScript书签相同/相对的文件夹中。


以下方法不适用于我的问题:

var scripts = document.getElementsByTagName("script");
var src = scripts[scripts.length-1].src;
alert("THIS IS: "+src);


与我的问题不相关的相关问题:


通常情况下它不起作用,但可能有解决方法。然而,您可以在脚本中放置一个静态变量来存储路径,该路径可能由服务器端脚本生成。 - Bergi
你的根本问题并不是很清楚。如果你有路径信息来创建脚本标签,那么将其作为变量或函数参数添加到代码中应该是微不足道的。 - charlietfl
我已经发布了我的当前方法(作为答案)。我曾提到我在当前的方法中使用了超时...但我意识到我没有! - webextensions.org
我不理解你所生成的使用案例,为什么需要如你回答中所描述的那样复杂的解决方案。请提供更多关于你试图实现什么、为什么(考虑到我们可能会为你提供替代方案)以及你目前面临的问题的信息... - Khez
2
为什么不在服务器端生成JS文件的某些部分,例如 var __domain = '$_HOST';?这将适用于任何浏览器,甚至是Netscape。 - c69
显示剩余5条评论
3个回答

4

我目前使用的解决方案虽然可行,但非常冗长:

var fnFullFilePathToFileParentPath = function(JSFullFilePath){
    var JSFileParentPath = '';
    if(JSFullFilePath) {
        JSFileParentPath = JSFullFilePath.substring(0,JSFullFilePath.lastIndexOf('/')+1);
    } else {
        JSFileParentPath = null;
    }
    return JSFileParentPath;
};

var fnExceptionToFullFilePath = function(e){
    var JSFullFilePath = '';

    if(e.fileName) {    // firefox
        JSFullFilePath = e.fileName;
    } else if (e.stacktrace) {  // opera
        var tempStackTrace = e.stacktrace;
        tempStackTrace = tempStackTrace.substr(tempStackTrace.indexOf('http'));
        tempStackTrace = tempStackTrace.substr(0,tempStackTrace.indexOf('Dummy Exception'));
        tempStackTrace = tempStackTrace.substr(0,tempStackTrace.lastIndexOf(':'));
        JSFullFilePath = tempStackTrace;
    } else if (e.stack) {   // firefox, opera, chrome
        (function(){
            var str = e.stack;
            var tempStr = str;

            var strProtocolSeparator = '://';
            var idxProtocolSeparator = tempStr.indexOf(strProtocolSeparator)+strProtocolSeparator.length;

            var tempStr = tempStr.substr(idxProtocolSeparator);
            if(tempStr.charAt(0)=='/') {
                tempStr = tempStr.substr(1);
                idxProtocolSeparator++;
            }

            var idxHostSeparator = tempStr.indexOf('/');
            tempStr = tempStr.substr(tempStr.indexOf('/'));

            var idxFileNameEndSeparator = tempStr.indexOf(':');
            var finalStr = (str.substr(0,idxProtocolSeparator + idxHostSeparator + idxFileNameEndSeparator));
            finalStr = finalStr.substr(finalStr.indexOf('http'));
            JSFullFilePath = finalStr;
        }());
    } else {    // internet explorer
        JSFullFilePath = null;
    }

    return JSFullFilePath;
};

var fnExceptionToFileParentPath = function(e){
    return fnFullFilePathToFileParentPath(fnExceptionToFullFilePath(e));
};

var fnGetJSFileParentPath = function() {
    try {
        throw new Error('Dummy Exception');
    } catch (e) {
        return fnExceptionToFileParentPath(e);
    }
};

var JSFileParentPath = fnGetJSFileParentPath();
alert('File parent path: ' + JSFileParentPath);

我期望得到比当前发布的答案更好的答案,因为当前的答案涉及错误处理,这会导致无法与IE调试一起使用。 - webextensions.org
按照我在这个答案中提到的原始解决方案进行操作...没有完美的解决方案,其他答案可能更容易根据要求实现。 - webextensions.org

1
var s = document.createElement('script'); 
s.setAttribute('src', 'code.js'); 
document.body.appendChild(s);

你不能简单地这样做吗?

var myScriptDir = 'http://somesite.tld/path-to-stuff/';
var s = document.createElement('script'); 
s.setAttribute('src', myScriptDir + 'code.js'); 
document.body.appendChild(s); 
// code inside http://somesite.tld/path-to-stuff/code.js will use myScriptDir to load futher resources from the same directory.

如果您不想让脚本内的代码负责加载其他资源,可以使用脚本标签的onload属性,例如s.onload=function(){...}。为了跨浏览器兼容性,您可能需要先加载jQuery,然后再使用getScript函数。相关链接包括http://www.learningjquery.com/2009/04/better-stronger-safer-jquerify-bookmarklethttp://api.jquery.com/jQuery.getScript/


0

有些评论已经提到了这一点,但我会尽量详细地阐述一下。

最简单、最跨浏览器、跨域的确定当前脚本路径的方法是在脚本本身中硬编码脚本路径

通常情况下,您可能正在加载第三方脚本文件,因此这是不可能的。但在您的情况下,所有的脚本文件都在您的控制之下。您已经添加了代码来加载资源(CSS、JS等),那么也可以包括脚本路径。


这种方法的问题在于当您想要移动文件时需要进行维护...似乎没有我想要的理想解决方案。 - webextensions.org
是的,维护是一个问题,但你可以在服务器端生成你的脚本(如@c9建议)或使用Grunt或类似的工具来重新生成你的脚本,如果/当你移动它们。重点是,查找当前脚本路径不是必须在浏览器上完成的工作。将你的脚本移动到其他地方是未来的可能性;无法在IE中进行调试是现实问题。 - Jeffery To

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接