【问题标题】:Get file path of currently executing JavaScript code for dynamically loaded cross domain JavaScript file获取动态加载的跨域 JavaScript 文件当前正在执行的 JavaScript 代码的文件路径
【发布时间】:2013-01-01 13:11:41
【问题描述】:

我需要加载跨域 JavaScript
我的站点中的书签动态文件http://jsbookmarklets.com/


解决方案应满足:

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


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


以下方法不适合我的问题:

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


不适合我的问题的相关问题:

【问题讨论】:

  • 我不明白为什么第一个相关问题没有回答你的问题。请告诉我们如何动态加载脚本,这对于获取路径非常重要。
  • 上述方法不适用于跨域JS文件
  • 只有第一句话是相关的:它一般不起作用,但可能有解决方法。但是,您可以在脚本中为您的路径放置一个静态变量,该变量可能由服务器端脚本生成。
  • 我正在使用 var s = document.createElement('script'); 加载新的 JavaScript 文件s.setAttribute('src', 'code.js'); document.body.appendChild(s);而且我相信这是跨域文件的唯一可能方式(现代跨域 AJAX(类似)请求不是一种选择,因为我需要一个适用于几乎任何随机网站的通用解决方案)
  • 为什么不简单地在服务器端生成 js 文件的某些部分,比如 var __domain = '$_HOST'; ?这适用于任何浏览器,包括网景。

标签: javascript jquery cross-domain bookmarklet


【解决方案1】:

我正在使用的当前解决方案,它有效,但非常冗长:

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 中进行调试。
  • 使用我在这个答案中提到的原始解决方案......没有完美的解决方案,其他答案可能更容易实施,具体取决于要求。
【解决方案2】:
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/

【讨论】:

    【解决方案3】:

    一些cmets已经提到了这一点,但我会尽量详细说明。

    找出当前脚本路径的最简单、最跨浏览器、跨域的方法是将脚本的路径硬编码到脚本本身中

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

    【讨论】:

    • 这种方法的问题是在您希望移动文件时进行维护......似乎没有理想的解决方案可以满足我的需求。
    • 是的,维护是一个问题,但您可以在服务器端生成脚本(如@c9 建议的那样)或使用Grunt 或类似工具在/何时(重新)生成脚本你移动它们。关键是,查找当前脚本的路径不是需要在浏览器上完成的工作。移动脚本是未来的可能性;现在无法在 IE 中调试是一个真正的问题。
    猜你喜欢
    • 1970-01-01
    • 2011-01-17
    • 1970-01-01
    • 2012-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-16
    • 2011-02-07
    相关资源
    最近更新 更多