如何在不使用 document.write() 的情况下为 CDN 库创建回退

How to create fallback for CDN libraries without using document.write()

我想包含来自 CDN 的第 3 方库,例如 jQuery。我还想创建一个回退,以便在 CDN 失败时包含我自己的本地副本。我遵循了建议 here:

这就是我在页面中包含 jQuery 的方式:

<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
<script>window.jQuery || document.write('<script src="/Scripts/jquery-3.3.1.min.js"><\/script>');</script>

同时Google is saying thatdocument.write()不可靠,不应该使用:

Using document.write() can delay the display of page content by tens of seconds and is particularly problematic for users on slow connections. Chrome therefore blocks the execution of document.write() in many cases, meaning you can't rely on it.

是否有任何替代方法来为 CDN 创建回退?

如果您不介意异步加载它,您可以这样做:

function fallback() {
  var element = document.createElement('script');
  element.type = 'text/javascript';
  element.src = 'https://code.jquery.com/jquery-3.3.1.min.js'; // or your path to your local script
  document.body.appendChild(element);
}

window.jQuery || fallback();

setTimeout(function() {
  console.log(window.jQuery);
}, 1000); // Add timeout since script is loaded asynchronously

我建议使用像 fallback.js or require.js 这样的 3p 包,因为如果您有多个回退,它们更具可扩展性,并且它们可以为您提供更快的加载性能。

Example of fallback.js

HTML代码

<html>
<head>
    <!-- **The `data-main` attribute tells the library to load `main.js`** -->
    <script async data-main="main" src="fallback.min.js" type="text/javascript"></script>
</head>

<body>
</body>
</html>

主要 JS 文件

cfg({
  "libs": {
    "jQuery": {
      "urls": [
        "//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min",
        "//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min"
      ]
    },  
  }
});

req(function(jQuery) {
  jQuery("body");
});

Example of require.js

requirejs.config({
  enforceDefine: true,
  paths: {
    jquery: [
      'https://code.jquery.com/jquery-3.4.1.min.js',
      //If the CDN location fails, load from this location
      'js/jquery-3.4.1.min.js'
    ]
  }
});

require(['jquery'], function ($) {});