相关脚本的CDN后备 [英] CDN Fallback for Dependant Scripts

查看:56
本文介绍了相关脚本的CDN后备的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我使用以下脚本:

  • jQuery
  • jQuery验证
  • jQuery验证不干扰
  • 引导程序

Bootstrap和jQuery验证需要jQuery和jQuery验证不打扰的需要jQuery验证,因此我们有相互依赖的脚本.我见过的所有后备脚本看起来都是这样的:

 (window.jQuery || document.write('< script src ="/bundles/jquery">< \/script>'));;($ .validator || document.write('< script src ="/bundles/jqueryval">< \/script>'));($ .validator.unobtrusive || document.write('< script src ="/bundles/jqueryvalunobtrusive">< \/script>'));;($ .fn.modal || document.write('< script src ="/bundles/bootstrap">< \/script>'));; 

问题是,如果我使用的是ajax.aspnetcdn.com CDN并失败,则第一行将导致jQuery在本地加载,但接下来的三行代码将在此之前执行,并且错误,因为$未定义

是否存在处理这些相互依赖的后备脚本类型的标准方法?我环顾四周,找不到用于处理这种情况的资源.

更新

我尽了最大的努力回答了这个问题,但我仍在寻找人们如何处理此问题的答案.

解决方案

依靠另一种第三方脚本似乎有些矫kill过正,但是我发现 YepNope.js 可能可以处理这种情况.对于CDN正常​​工作的日常情况,我不确定性能的影响.更多信息此处.>

我还可以编写自己的实现:

JavaScript后备广告

 (功能(文​​档,后备){var check = function(fallbacks,i){如果(i< fallbacks.length){var fallback = fallbacks [i];如果(fallback.test()){检查(后备,我+1);}别的 {var script = document.createElement("script");script.onload = function(){检查(后备,我+1);};script.src = fallback.src;document.getElementsByTagName("body")[0] .appendChild(script);}}}检查(fallbacks,0);})(文档, [{test:function(){返回window.Modernizr;},src:"/js/modernizr.js"},{test:function(){返回window.jQuery;},src:"/js/jquery.js"},{test:function(){return $ .validator;},src:"/js/jquery-validate.js"},{test:function(){return $ .validator.unobtrusive;},src:"/js/jquery-validate-unobtrusive.js"},{test:function(){return $ .fn.modal;},src:"/js/bootstrap.js"},{test:function(){返回窗口.Hammer&window.Hammer.VERSION;},src:"/js/hammer.js"},{test:function(){返回window.Zepto;},src:"/js/bootstrap-touch-carousel.js"}]); 

CSS后备广告

使用元标记的想法是从新的ASP.NET 5 MVC 6框架借用"的.

 (功能(文​​档,后备){var metas = document.getElementsByTagName("meta");for(var i = 0; i< fallbacks.length; ++ i){var fallback = fallbacks [i];for(j = 0; j< metas.length; ++ j){var meta = metas [j];如果(meta.getAttribute("name")== fallback.metaName){如果(!fallback.test(meta)){var link = document.createElement("link");link.href = fallback.href;link.rel =样式表";document.getElementsByTagName("head")[0] .appendChild(link);}休息;}}}})(文档, [{//metaName-执行测试的meta标记的名称.元标记必须具有来自//相关的样式表,以便对其进行样式设置并可以对其进行测试.例如.为了//字体很棒<元名称="x-font-awesome-stylesheet-fallback-test" class ="fa">元标记为//           添加."fa"类导致将字体真棒样式应用到它.metaName:"x-font-awesome-stylesheet-fallback-test",//测试-针对meta标签执行的测试.检查是否加载了字体真棒样式//通过检查meta标签的字体系列是否为'FontAwesome'成功.测试:function(meta){return meta.style.fontFamily ==="FontAwesome";},//href-后备样式表的URL.href:"/css/font-awesome.css"}]); 

If I am using the following scripts:

  • jQuery
  • jQuery Validation
  • jQuery Validation Unobtrusive
  • Bootstrap

Bootstrap and jQuery Validation require jQuery and jQuery Validation Unobtrusive requires jQuery Validation so we have interdependent scripts. The fallback scripts I have seen all look something like this:

(window.jQuery || document.write('<script src="/bundles/jquery"><\/script>'));
($.validator || document.write('<script src="/bundles/jqueryval"><\/script>'));
($.validator.unobtrusive || document.write('<script src="/bundles/jqueryvalunobtrusive"><\/script>'));
($.fn.modal || document.write('<script src="/bundles/bootstrap"><\/script>'));

The problem is that if I am using the ajax.aspnetcdn.com CDN and it fails, then the first line will cause jQuery to be loaded locally but the next three lines of code will execute before that and error because $ is undefined.

Is there a standard way to handle these types of interdependent fall-back scripts? I have looked around and can't find a resource for handling this type of scenario.

UPDATE

I answered the question as best I can but I'm still looking for an answer on how people handle this.

解决方案

It seems overkill to rely on yet another third party script but I have discovered Fallback.js and YepNope.js which may be able to handle this scenario. I am not sure about the performance implications of the everyday scenario where the CDN's just work. More info here.

I also had a go at writing my own implementations:

JavaScript Fallbacks

(function (document, fallbacks) {

    var check = function (fallbacks, i) {
        if (i < fallbacks.length) {
            var fallback = fallbacks[i];
            if (fallback.test()) {
                check(fallbacks, i + 1);
            }
            else {
                var script = document.createElement("script");
                script.onload = function () {
                    check(fallbacks, i + 1);
                };
                script.src = fallback.src;
                document.getElementsByTagName("body")[0].appendChild(script);
            }
        }
    }
    check(fallbacks, 0);

})(document, [
    { test: function () { return window.Modernizr; }, src: "/js/modernizr.js" },
    { test: function () { return window.jQuery; }, src: "/js/jquery.js" },
    { test: function () { return $.validator; }, src: "/js/jquery-validate.js" },
    { test: function () { return $.validator.unobtrusive; }, src: "/js/jquery-validate-unobtrusive.js" },
    { test: function () { return $.fn.modal; }, src: "/js/bootstrap.js" },
    { test: function () { return window.Hammer && window.Hammer.VERSION; }, src: "/js/hammer.js" },
    { test: function () { return window.Zepto; }, src: "/js/bootstrap-touch-carousel.js" }
]);

CSS Fallbacks

The idea for using a meta tag was 'borrowed' from the new ASP.NET 5 MVC 6 framework.

(function (document, fallbacks) {

    var metas = document.getElementsByTagName("meta");

    for (var i = 0; i < fallbacks.length; ++i) {
        var fallback = fallbacks[i];

        for (j = 0; j < metas.length; ++j) {
            var meta = metas[j];
            if (meta.getAttribute("name") == fallback.metaName) {
                if (!fallback.test(meta)) {
                    var link = document.createElement("link");
                    link.href = fallback.href;
                    link.rel = "stylesheet";
                    document.getElementsByTagName("head")[0].appendChild(link);
                }
                break;
            }
        }

    }

})(document, [
    {
        // metaName - The name of the meta tag that the test is performed on. The meta tag must have a class from the
        //            relevant stylesheet on it so it is styled and a test can be performed against it. E.g. for 
        //            font awesome the <meta name="x-font-awesome-stylesheet-fallback-test" class="fa"> meta tag is
        //            added. The 'fa' class causes the font awesome style to be applied to it.
        metaName: "x-font-awesome-stylesheet-fallback-test",
        // test - The test to perform against the meta tag. Checks to see if the Font awesome styles loaded 
        //        successfully by checking that the font-family of the meta tag is 'FontAwesome'.
        test: function (meta) { return meta.style.fontFamily === "FontAwesome"; },
        // href - The URL to the fallback stylesheet.
        href: "/css/font-awesome.css"
    }
]);

这篇关于相关脚本的CDN后备的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆