【问题标题】:How do you synchronously load a script from another directory via an ajax call?如何通过 ajax 调用从另一个目录同步加载脚本?
【发布时间】:2011-05-31 04:44:42
【问题描述】:

我经常需要通过ajax加载其他javascript文件,所以一开始我使用了jQuery提供的标准函数来进行脚本加载:

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

但这并没有成功,因为 $.getScript 是异步的($.ajax 的 jQuery API 说'async' 默认设置为 true;主题在 $.getScript API 的 cmets 中讨论: http://api.jquery.com/jQuery.getScript/)。所以我写了这个函数,正如上面链接的API页面的cmets中有人提供的那样:

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') 根本不起作用。

感觉好像我遗漏了一些明显的东西,但我没能找到问题所在。有什么想法吗?

【问题讨论】:

    标签: javascript jquery ajax


    【解决方案1】:

    默认情况下,您可以使用ajaxSetup 将 ajax 调用设置为同步。看起来是这样的:

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

    如果您再次需要异步调用,只需启用它:

    $.ajaxSetup({async:true});
    

    【讨论】:

    • 将 ajax 模式设置为同步对我有用,但重要的是:如果您传递回调函数 callback_function(),请省略括号。否则传递函数的返回值并在 before getScript() 执行 callback_function ins
    • 不推荐使用$.ajaxSetup - 请参阅api.jquery.com/jquery.ajaxsetup。更改 ajax 调用的 async 属性默认值不是一个好主意。 $.Getscript$.ajax 的简写,所以你可以这样做:$.ajax({ url: url, dataType: "script", async: true }) - 适合我。
    【解决方案2】:

    更新:见下方评论流,与jQuery无关,是服务器文件权限问题。


    原答案

    您是否从浏览器中收到任何错误?例如,在 Chrome 或 Safari 中,如果您打开开发工具并查看控制台选项卡,它会显示错误吗?或者在 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。很奇怪。如果您将 same 脚本移动到不在子路径上,它会起作用吗?我想知道子路径是不是红鲱鱼,真正的问题是脚本中的语法错误。


    题外话真的必须是同步的吗?您不能只轮询出现的符号吗?只是同步 ajax 请求真的会破坏用户体验。在许多浏览器中,不仅是您自己的页面,而且所有页面在请求期间都会被锁定。

    这就是轮询的意思:假设我想从 JavaScript 异步加载 jQuery:

    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's 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'
    });
    

    【讨论】:

    • 错误函数没有帮助 - textStatus 设置为 'error' 并且 errorThrown 未定义。
    • @Alex:确实很奇怪。顺便说一句,我添加了一个巨大的离题评论。 :-) 是您的实际问题,如果您移动它以使其不在子路径上,相同的脚本是否可以工作?不知道子路径是不是红鲱鱼,真正的问题是脚本中的语法错误。
    • Firebug 提供了帮助,请求因 403 错误而失败!我在安装在我的 Ubuntu 上的本地服务器上,我不知道如何解决这个问题?关于题外话问题:好吧,我想在加载脚本后执行函数,并使用 $.getScript(script_url,function_from_the_loaded_script());它没有用。
    • @Alex:403 听起来像是服务器设置问题;如果你在浏览器窗口中输入完整路径,你能看到脚本吗? SOP 或类似的东西不应该有任何路径方面。我刚刚试了一下,效果很好。
    • @Alex:啊,好吧,这就是问题所在。您需要查看您的 Web 服务器以哪个用户身份运行,并确保该用户对子目录条目及其中的文件具有读取权限。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-10
    • 2014-06-20
    • 1970-01-01
    相关资源
    最近更新 更多