Bootstrap Javascript 和 CSS 的 3 个回退

Bootstrap 3 fallback for Javascript and CSS

昨天我所有的 Bootstrap 3.3.x 站点都没有从 MaxCdn(在荷兰)加载 js/css 文件,所以今天我搜索了一个后备方案。 JQuery 很简单,但是对于 Bootstrap CSS 我只找到将本地 css 文件作为开头第一行的示例。以下代码是我到目前为止将本地 Bootstrap CSS 放在正确位置以防回退的代码。

在头部:

<meta charset="utf-8">
<title>CDN fallback</title>
<link id="cssbs" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/ABC_bootstrap.min.css">
<link id="csscu" rel="stylesheet" href="style.css">
<meta name="author" content="Foo">

正文结尾:

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/ABC_jquery.min.js"></script>
<script>
window.jQuery || document.write('<script src="lib/jquery-1.11.1/jquery.min.js"><\/script>')
</script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/ABC_bootstrap.min.js"></script>
<script>
if(typeof($.fn.modal) === 'undefined'){
  document.write('<script src="lib/bootstrap-3.3.5/js/bootstrap.min.js"><\/script>')
}
$(document).ready(function(){
  var bodyColor = $('body').css('color');
  var localCss  = '<link rel="stylesheet" href="lib/bootstrap-3.3.5/css/bootstrap.min.css">';
  if(bodyColor != 'rgb(51, 51, 51)'){
    $("#cssbs").replaceWith(localCss);
  }
});
</script>

我的问题:性能怎么样?有更好的后备建议吗?

注意:为了测试,我在 CDN 文件名中输入了 ABC。

谢谢罗纳德

为 CDN 执行回退加载的一种方法是让 scripts/stylesheets 异步加载超时,这样如果 CDN 响应时间太长(因为它可能已关闭),您加载一个在合理的时间内替换文件。为此,您可以实现一个功能,例如下面的 fallbackLoad,并将其放在 HTML 页面的 HEAD 部分。

function fallbackLoad(urls, callback, timeout) {
    var url = urls.shift()
    timeout = timeout || undefined;
    callback = callback || function() {};
    var error = (function(urls, callback) {
        return function() {
            if (urls.length == 0) {
                console.error('Failed to fallback, all urls down');
            } else {
                makeRequest(urls.shift(), callback, error);
            }
         };
    })(urls, callback);
    return makeRequest(url, callback, error);
}

然后将您的 makeRequest 函数定义为

function makeRequest(url, success, error, timeout) {
    var xhr = new XMLHttpRequest();
    if (timeout) {
        xhr.ontimeout = error;
    }
    xhr.onload = function() {
        if (xhr.readyState === 4) { 
            if (xhr.status === 200) {
                success(xhr.responseText);
            } else {
                error();
            }
         }
    };
    xhr.open("GET", url, true /* async */);
    if (timeout) xhr.timeout = timeout;
    xhr.send(null);
}

现在您可以在脚本的 HEAD 中调用 fallbackLoad,而不会阻止页面加载。你可以称它为

fallbackLoad([
    '//ajax.googleapis.com/ajax/libs/jquery/1.11.1/ABC_jquery.min.js',
    'lib/jquery-1.11.1/jquery.min.js'
], function(response) {
    ....
}, 500 /* ms */);