Javascript 如何确定$.getScript的url

Javascript 如何确定$.getScript的url,javascript,jquery,ajax,Javascript,Jquery,Ajax,我创建了一个JavaScript文件,需要知道它的来源位置。在脚本内部,我有以下代码来确定JavaScript文件的url var url = (function () { if (module) { // resolve URL from module - RequireJS return module.uri; } else { // resolve URL from currentScript - Firefox &a

我创建了一个JavaScript文件,需要知道它的来源位置。在脚本内部,我有以下代码来确定JavaScript文件的url

var url = (function () {
    if (module) {
        // resolve URL from module - RequireJS
        return module.uri;
    }
    else {
        // resolve URL from currentScript - Firefox & Chrome
        if (document.currentScript) {
            return document.currentScript.src;
        }
        // resolve URL from DOM - Internet Explorer
        else {
            var scripts = document.getElementsByTagName('script'),
            script = scripts[scripts.length - 1];

            if (script.getAttribute.length !== undefined) {
                return script.src;
            }
            return script.getAttribute('src', -1);
        }
    }
}());
我希望能够使我的JavaScript文件与使用jQuery的
$.getScript
(与
$.ajax
调用相同)的人兼容。不幸的是,我还没有弄清楚在使用url时如何获取它。我想到的一个选择是:

var ScriptUrl = "https://example.com/myscript.js";
var callback = function () {
    console.log("Callback");
}
$.getScript(ScriptUrl, callback);
然后,我可以检查脚本中的变量
ScriptUrl
,但出于明显的原因,我不喜欢这个解决方案

var url = ScriptUrl ? ScriptUrl : (function () {
    // ...
}());

我不知道它有多可靠,但唯一有效的方法是在
myscript.js
的开头使用
ajaxComplete
钩子和一个神奇的唯一标识符。这对于跨域请求不起作用,因为您无法访问
responseText
,但在这种情况下,您可能可以扫描
脚本
标记

调用
myscript
的回调时,您将检查
responseText
是否以该唯一标识符开头,如果是,则
ajaxOptions
中的
url
应该是您的脚本之一

//unique-identifier
$( document ).ajaxComplete(function(event, jqXHR, ajaxOptions) {
  if( /^\/\/unique-identifier/.test(jqXHR.responseText) ) {
     console.log('my url is: '+ajaxOptions.url);
  }
});

console.log('is executed before the "ajaxComplete"');
如果您确定名称
myscript.js
本身是唯一的,那么您应该能够对相同和跨域请求使用相同的技术,并且您不需要该注释

当您的代码应该被执行时,您确实需要添加一些更多的逻辑,因为您可以看到
控制台。log
将在
url
已知之前被执行。您可能需要检查
jQuery
是否存在

也许是这样的:

//unique-identifier
(function() {
  var ScriptUrl;

  function init() {

    console.log('init');
  }


  if( window.jQuery ) {
    jQuery( document ).ajaxComplete(function(event, jqXHR, ajaxOptions) {
      if( /^\/\/unique-identifier/.test(jqXHR.responseText) ) {
        ScriptUrl = ajaxOptions.url;
        init();
      }
    });
  } else {
    //do some error handling or support an altnerative loader like requirejs
  }

}());

我采用了t.niese提出的解决方案,并将其应用于我的原始代码
uniqueKey
是一个字符串,用于确定url是否为脚本的url。如果用户没有使用
RequireJS
,我假设在执行此代码之前已经加载了
jQuery

(function (factory) {
    // Support module loading scenarios
    if (typeof define === 'function' && define.amd) {
        // AMD Anonymous Module
        define(['jquery', 'module'], factory);
    } else {
        // No module loader
        factory(jQuery);
    }
})(function ($, module) {
    // Used to determine whether the url is for the script
    var uniqueKey = 'myscript.js';

    var urlPromise = (function () {
        // Check if the url is the correct one
        var validUrl = function(url) {
            return url ? url.indexOf(uniqueKey) > -1 : false; 
        };

        return (function () {
            var deferred = jQuery.Deferred();

            if (document.currentScript && validUrl(document.currentScript.src)) {
                // Chrome & Firefox
                deferred.resolve(document.currentScript.src);
            }
            else if (module && validUrl(module.uri)) {
                // RequireJS
                deferred.resolve(module.uri);
            }
            else {
                // DOM
                var scripts = document.getElementsByTagName('script');
                var script = scripts.length > 0 ? scripts[scripts.length - 1] : null;

                if (script && script.getAttribute.length !== undefined && validUrl(script.src)) {
                    deferred.resolve(script.src);
                }
                else if (script && validUrl(script.getAttribute('src', -1))) {
                    deferred.resolve(script.getAttribute('src', -1));
                }
                else {
                    // AJAX request
                    jQuery(document).ajaxComplete(function(event, jqXHR, ajaxOptions) {
                        if (ajaxOptions && validUrl(ajaxOptions.url)) {
                            deferred.resolve(ajaxOptions.url); 
                        }
                    });
                }
            }        
            return deferred;
        }());
    }());

    urlPromise.then(function(scriptUrl) {
        console.log(scriptUrl);
    });
});

令人惊叹的我不知道
ajaxCompleted
函数。您如何确定是使用
ajaxCompleted
还是查看
脚本
标记?同样不幸的是,我需要做跨域请求。。。但除非有人提出更好的解决方案,否则我仍会将此标记为正确的。查看
myscript.js
的要点很好。这将始终是相同的,所以我可以肯定地使用它。@Dehli如果是这种情况,那么您可以使用
ajaxCompleted
,因为对于跨域请求,
ajaxOptions.url
将被设置,只有
jqXHR.responseText
将为空。我想-但是我需要对jQuery做一些代码检查-对
jQuery(document.ajaxComplete
的第一次调用将始终是针对脚本本身的。谢谢!我会把它弄得乱七八糟的。我将用我提出的任何意见添加评论。@Dehli可以提供一个完整的解决方案,并将您的意见标记为已接受的意见,而不是添加评论。您的
var script=scripts[scripts.length-1]可能会失败,因为页面的维护者可能已经删除了所有脚本标记-不太可能,但可能会发生。不确定
模块
应该/将如何工作,但如果页面中不包含requirejs,或者代码中缺少包装函数,则未定义
模块
,这将引发异常。我在代码中有一个包装函数,这样代码行就不会引发异常。我感谢所有的反馈!