Как вы синхронно загружаете script из другого каталога через вызов ajax?

Мне часто приходится загружать другие файлы javascript через ajax, поэтому в начале я использовал стандартную функцию jQuery для script загрузки:

$.getScript('script_name.js',callback_function());

Но это не сработало, поскольку $.getScript асинхронен (jQuery API для $.ajax говорит, что "async" по умолчанию установлено значение true, тема обсуждается в комментариях API для $.getScript: http://api.jquery.com/jQuery.getScript/). Поэтому я написал эту функцию, предоставленную кем-то в комментариях страницы API, приведенной выше:

load:function(script,callback){

    jQuery.ajax({

        async:false,

        type:'GET',

        url:script,

        data:null,

        success:callback,

        dataType:'script'

    });

},

Казалось, что это хорошо работает, поэтому я продолжил, но недавно заметил, что это работает только для скриптов в одном каталоге, например. вызов myObj.load('test.js') работает хорошо, но вызов myObj.load('test/test.js') не работает вообще.

Похоже, что мне не хватает чего-то очевидного, но мне не удалось найти проблему. Любая идея?

Ответы

Ответ 1

Обновление: см. поток комментариев ниже, это не имеет никакого отношения к jQuery, это проблема с правами на файл на сервере.


Оригинальный ответ:

Есть ли у вас ошибки в браузере? Например, в Chrome или Safari, если вы откроете Dev Tools и посмотрите вкладку Console, отобразите ошибки? Или в Firefox установите Firebug и проверьте консоль Firebug. Или в IE, используйте бесплатную версию VS.Net... Что-то должно жаловаться на что-то о чем-то.

Вы также можете получить больше информации от своего кода, предоставив функцию error, а не предполагая успех:

jQuery.ajax({
    async:false,
    type:'GET',
    url:script,
    data:null,
    success:callback,
    dataType:'script',
    error: function(xhr, textStatus, errorThrown) {
        // Look at the `textStatus` and/or `errorThrown` properties.
    }
});

Обновление. Вы сказали, что видите textStatus= 'error' и errorThrown= undefined. Очень странно. Работает ли тот же script, если вы переместите его так, чтобы он не был в подпути? Интересно, является ли подпуть красной селедой, а реальной проблемой является синтаксическая ошибка в script.


Вне темы: действительно ли это должно быть синхронно? Вы не можете просто проголосовать за появление символа? Это просто, что синхронный запрос ajax действительно избавляет пользователя от необходимости. Во многих браузерах во время запроса блокируется не только ваша страница, но все.

Вот что я имею в виду под опросом: предположим, что я хотел асинхронно загрузить jQuery из JavaScript:

function loadScript(url, symbol, callback) {
    var script, expire;

    // Already there?
    if (window[symbol]) {
        setTimeout(function() {
            callback('already loaded');
        }, 0);
    }

    // Determine when to give up
    expire = new Date().getTime() + 20000; // 20 seconds

    // Load the script
    script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = url;
    document.body.appendChild(script);

    // Start looking for the symbol to appear, yielding as
    // briefly as the browser will let us.
    setTimeout(lookForSymbol, 0);

    // Our symbol-checking function
    function lookForSymbol() {
        if (window[symbol]) {
            // There the symbol, we're done
            callback('success');
        }
        else if (new Date().getTime() > expire) {
            // Timed out, tell the callback
            callback('timeout');
        }
        else {
            // Schedule the next check
            setTimeout(lookForSymbol, 100);
        }
    }
}

Использование:

// Load jQuery:
loadScript("path/to/jquery.min.js", "jQuery", function(result) {
    // Look at 'result'
});

Ответ 2

Вы можете установить ajax-вызовы синхронно по умолчанию, используя ajaxSetup. Вот как это выглядит:

$.ajaxSetup({async:false});
$.getScript('script_name.js', callback_function);

Если вам нужны асинхронные вызовы снова, просто включите его с помощью:

$.ajaxSetup({async:true});