Javascript 检测是否为CDN回退加载了角度相关性[角度路由、角度资源等]

Javascript 检测是否为CDN回退加载了角度相关性[角度路由、角度资源等],javascript,angularjs,cdn,fallback,Javascript,Angularjs,Cdn,Fallback,我在ASP.NET MVC 4上使用Angular JS,我使用脚本包从cdn加载,并且在cdn出现故障时也从源服务器加载,如下所示: var jQuery = new ScriptBundle("~/bundles/scripts/jquery", "//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js") // CDN .Include("~/Scripts/jquery-{ver

我在ASP.NET MVC 4上使用Angular JS,我使用脚本包从cdn加载,并且在cdn出现故障时也从源服务器加载,如下所示:

var jQuery = new ScriptBundle("~/bundles/scripts/jquery",
            "//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js") // CDN
            .Include("~/Scripts/jquery-{version}.js");  // Local fallback
jQuery.CdnFallbackExpression = "window.jQuery"; // Test existence
bundles.Add(jQuery);

分别使用window.jQuery和window.Angular可以很容易地检测jQuery或AngularJS是否存在。ASP.NET绑定机制评估CdnFallbackExpression文本,以查看它是否需要返回到源服务器

但是,在AngularJS的更高版本中,其他模块(如ngRoute和ngResource)被分离到各自的文件中,由开发人员自行加载

如何检测是否加载了其他AngularJS模块?我可以在控制台中键入什么来查看ngAnimate、ngRoute、ngResource等是否成功从CDN加载?

我使用的是:

<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.5.0/ui-bootstrap.min.js"></script>
<script>
  try { //try to load from cdn
    //use the name of the angular module here
    angular.module('ui.bootstrap');
  } 
  catch(e) { //error thrown, so the module wasn't loaded from cdn
    //write into document from local source
    document.write('<script src="sys/lib/ui-bootstrap.js"><\/script>'); 
  }
</script>

尝试{//尝试从cdn加载
//在此使用角度模块的名称
angular.module('ui.bootstrap');
} 
catch(e){//抛出错误,因此模块不是从cdn加载的
//从本地源写入文档
文件。写(“”);
}

angular.module
如果没有这样的模块,就会抛出一个错误,这正是我们需要知道的
try/catch
在这里非常好。

这里有一种方法,专门用于您在OP中提供的Microsoft优化框架

angularjsRoute.CdnFallbackExpression = @"
    function() { 
        try { 
            window.angular.module('ngRoute');
        } catch(e) {
            return false;
        } 
        return true;
    })(";
此表达式本身不是有效的javascript,但MS优化框架使用此表达式并最终向页面生成以下输出。现在我们有了一个有效的自执行javascript函数,它根据angular模块是否加载返回true或false

<script>(
function() { 
    try {
        window.angular.module('ngRoute');
    }
    catch(e) {
        return false;
    }

    return true;
})()||document.write('<script src="/bundles/scripts/angularjs-route"><\/script>');</script>
(
函数(){
试一试{
window.angular.module('ngRoute');
}
捕获(e){
返回false;
}
返回true;
})()||文件。写(“”);
(qntmfred答案的变化。)

与其留下奇怪的左括号,不如使用一个正常的立即调用函数

结果就是,优化框架将把这一点用另一组括号括起来,但会让您的C#更加清晰

angularjsRoute.CdnFallbackExpression = 
    @"(function() { 
        try { 
            window.angular.module('ngRoute');
        } catch(e) {
            return false;
        } 
        return true;
    })()";
另一个变体

<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.14.3/ui-bootstrap-tpls.min.js"></script>
<script>
    try {
        window.angular.module('ui.bootstrap');
    }
    catch(e) {
        var script = document.createElement('script');
        script.src = 'lib/bootstrap/dist/js/bootstrap.js';
        document.getElementsByTagName('head')[0].appendChild(script);
    }
</script>

试一试{
window.angular.module('ui.bootstrap');
}
捕获(e){
var script=document.createElement('script');
script.src='lib/bootstrap/dist/js/bootstrap.js';
document.getElementsByTagName('head')[0].appendChild(脚本);
}

可能
角度。模块('moduleName')
工作。如果模块不存在,它可能会抛出异常,但我不确定这样做是否正确。@gustavohenke我在玩弄它,但你是对的,注入器会生气。非常生气。如果你能将它包装在一个
try..catch
块中,可能就是这样:)使用require.js和angular loader作为编译版本的语句也不是有效的javascript,Chrome中的控制台也不是。
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.14.3/ui-bootstrap-tpls.min.js"></script>
<script>
    try {
        window.angular.module('ui.bootstrap');
    }
    catch(e) {
        var script = document.createElement('script');
        script.src = 'lib/bootstrap/dist/js/bootstrap.js';
        document.getElementsByTagName('head')[0].appendChild(script);
    }
</script>