Получить URL-адрес текущего исполняемого файла JS при динамической загрузке - PullRequest
9 голосов
/ 17 февраля 2010

Итак, я пытаюсь загрузить скрипт динамически и выяснить URL-адрес, по которому этот скрипт был загружен. Поэтому какой-то парень дал мне довольно классное решение этой проблемы, если сценарии загружены статически ( Как получить путь к файлу исполняемого в данный момент кода JavaScript ). Но мне нужно динамически загружаемое решение. Например:

$(function()
{   $.getScript("brilliant.js", function(data, textStatus)
    {   // do nothing   
    });
});

где "brilliant.js" имеет:

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

В идеале для этого следует либо распечатать "brilliant.js", либо "& lang; имя хоста + базовый путь & rang; /brilliant.js"

В настоящее время brilliant.js работает для статически включаемых сценариев, но не для сценариев, включаемых динамически (как с $ .getScript). У кого-нибудь есть идеи? Есть ли где-нибудь в dom, где хранятся все загруженные скрипты?

РЕДАКТИРОВАТЬ: Андрас дал довольно хорошее решение, хотя, вероятно, это работает только для jQuery. Поскольку это, наверное, самая популярная библиотека, и определенно то, что я собираюсь использовать. Вероятно, он может быть расширен и для других библиотек. Вот моя упрощенная версия:

var scriptUri;
curScriptUrl(function(x)
{   scriptUri = x;
    alert(scriptUri);
});

function curScriptUrl(callback)
{   var scripts = document.getElementsByTagName("script");
    var scriptURI = scripts[scripts.length-1].src;  

    if(scriptURI != "")         // static include
    {   callback(scriptURI);
    }else if($ != undefined)    // jQuery ajax
    {   $(document).ajaxSuccess(function(e, xhr, s)
        {   callback(s.url);
        }); 
    }
}

Ответы [ 3 ]

8 голосов
/ 20 февраля 2010

Когда ваш скрипт будет загружен с помощью jQuery (и я предполагаю, что и другие фреймворки), ваш скрипт станет неотличимым от скрипта, который изначально был в документе HTML.

jQuery отправляет запрос на ваш скрипт и возвращает ответ как текстовый дочерний элемент узла . Ваш браузер не может знать, откуда он возник, был ли он изменен перед вставкой и т. Д. Для него это просто узел сценария.

Однако могут быть обходные пути. В случае с jQuery вы можете подключиться к событиям ajax и использовать тот факт, что они вызываются сразу после выполнения вашего скрипта. По сути, это приведет к "brilliant.js" в вашем примере:

var handler = function (e, xhr, s) {
    alert(s.url);
}

$(document).ajaxSuccess(handler);

Более сложный:

(function ($, undefined) {

    /* Let's try to figure out if we are inlined.*/
    var scripts = document.getElementsByTagName("script");

    if (scripts[scripts.length - 1].src.length === 0) {
        // Yes, we are inlined.
        // See if we have jQuery loading us with AJAX here. 
        if ($ !== undefined) {
            var initialized = false;
            var ajaxHandler = function (e, xhr, s) {
                if (!initialized) {
                    initialized = true;
                    alert("Inlined:" + s.url);
                    initmywholejsframework();
                }
            }

            //If it is, our handler will be called right after this file gets loaded.
            $(document).ajaxSuccess(ajaxHandler);

            //Make sure to remove our handler if we ever yield back.
            window.setTimeout(function () {
                jQuery(document).unbind("ajaxSuccess", ajaxHandler);
                if (!initialized) {
                    handleInlinedNonjQuery();
                }
            }, 0);

        }
    } else {
        //We are included.
        alert("Included:" + scripts[scripts.length - 1].src);
        initmywholejsframework();
    }

    //Handle other JS frameworks etc. here, if you will.
    function handleInlinedNonjQuery() {
        alert("nonJQuery");
        initmywholejsframework();
    }

    //Initialize your lib here
    function initmywholejsframework() {
        alert("loaded");
    }

})(jQuery);
0 голосов
/ 22 февраля 2010

Это будет работать в любом браузере, кроме IE, и не зависит от предположения, как называется файл:

var getErrorLocation = function (error) {
    var loc, replacer = function (stack, matchedLoc) {
        loc = matchedLoc;
    };

    if ("fileName" in error) {
        loc = error.fileName;
    } else if ("stacktrace" in error) { // Opera
        error.stacktrace.replace(/Line \d+ of .+ script (.*)/gm, replacer);
    } else if ("stack" in error) { // WebKit
        error.stack.replace(/at (.*)/gm, replacer);
        loc = loc.replace(/:\d+:\d+$/, ""); // remove line number
    }
    return loc;
};

try {
    0();
} catch (e) {
    var scriptURI = getErrorLocation(e);
}

alert("THIS IS: " + scriptURI);
0 голосов
/ 17 февраля 2010

B T, извините, если это не поможет, но мне любопытно, зачем вам это нужно? Причина, по которой я спрашиваю, состоит в том, что я не понимаю, почему вы не можете просто использовать относительные пути к файлам для загрузки этих файлов? Выяснить, где вы находитесь, можно с помощью window.location, но зачем вам это? А что касается их загрузки, вы не можете сделать ajax-вызов файла и затем проверить их?

...