如何使用完整性和跨域预加载脚本

How to preload script using integrity and crossorigin

我希望为我的 Jquery 库使用预加载并使用以下代码。

<link rel="preload" href="https://code.jquery.com/jquery-3.4.0.slim.min.js" as="script" integrity="sha256-ZaXnYkHGqIhqTbJ6MB4l9Frs/r7U4jlx7ir8PJYBqbI="
  crossorigin="anonymous">

<script
  src="https://code.jquery.com/jquery-3.4.0.slim.min.js"
  integrity="sha256-ZaXnYkHGqIhqTbJ6MB4l9Frs/r7U4jlx7ir8PJYBqbI="
  crossorigin="anonymous"></script>

然而,这总是在 chrome 内生成以下警告。

  1. 已找到“https://code.jquery.com/jquery-3.4.0.slim.min.js”的预加载,但由于完整性不匹配而未使用。

  2. 资源 https://code.jquery.com/jquery-3.4.0.slim.min.js 是使用 link 预加载预加载的,但在 window 的加载事件后几秒钟内未使用。请确保它具有适当的 as 值,并且是有意预加载的。

如果我使用标准实现,下面的代码将工作正常。

<link rel="preload" href="https://code.jquery.com/jquery-3.4.0.slim.min.js" as="script">

<script>
  src="https://code.jquery.com/jquery-3.4.0.slim.min.js"
</script>

所以我的问题是我可以预加载外部库并同时使用跨源和完整性(子资源完整性)吗?

谢谢

简答:你不能。

具有完整性属性的资源不能重用预加载的资源(目前),也可能导致双重提取。 link 元素的 integrity 属性尚未实现,并且有一个关于它的开放规范 issue。这意味着任何完整性元数据的存在当前都会丢弃预加载的资源。在野外,它还可能导致重复请求,您必须在安全性和性能之间做出 trade-off。

现在有几个浏览器支持它。 Chromium issue 其他回答中提到的目前已关闭。 Firefox 和 Safari 似乎也支持此功能。

挖掘这个主题以添加一些以前未提及的当前行为。

目前,截至 2020 年底,对于 preload 需要 integritycrossorigin 属性的资源,必须在两个标签中指定这两个属性 <link><script> 以及 必须匹配 ,才能有效预加载。


例子

<link rel="preload" href="http://..." integrity="sha..." crossorigin="anonymous" as="style" />
<link rel="stylesheet" href="http://..." integrity="sha..." crossorigin="anonymous" type="text/css" media="all" />

如果不遵守,控制台会发出警告:

The resource http://... was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate "as" value and it is preloaded intentionally.

就我而言,我试图滚动到具有固定 header 的页面顶部。我在 Chrome.

的控制台中收到以下警告
The resource https://xxxxxx.com/xxx.js
was preloaded using link preload but not used within a few seconds from
the window’s load event. Please make sure it has an appropriate as value
and it is preloaded intentionally.

我通过添加 setTimeout 函数解决了这个问题。 (稍微延迟一下,以便您的 scrollTo() 操作可以在 Chrome 默认滚动到 html 锚点事件后触发。)JavaScript issue with scrollTo() in Chrome

所以我从

更改了来源
scrollTop() {
    window.scrollTo(0, 0)
},

scrollTop() {
  setTimeout(function () {
    window.scrollTo(0, 0)
  }, 10)
},