为什么预加载链接不适用于JSON请求?

时间:2017-01-14 23:00:17

标签: javascript json html5 w3c

我网站上的JavaScript加载了几个JSON来初始化自己。

我想预先加载它们,当JavaScript在其上启动Ajax请求时,它们将立即加载。

存在新的link标记。

我试图用它来加载像这样的JSON:

<link rel="preload" href="/test.json">

但是,Chrome似乎加载了两次,并在控制台中显示警告:

资源test.json是使用链接预加载预加载的,但是在窗口加载事件的几秒钟内没有使用。请确保它没有预先加载。

所以似乎preload对JSON不起作用。 实际上,我没有在the specification中找到对JSON的引用。

这是正确的还是我做错了?

10 个答案:

答案 0 :(得分:6)

根据https://developer.mozilla.org/en-US/docs/Web/HTML/Preloading_content,您必须为JSON文件添加as="prefetch"。 所以你的代码变成了

<link rel="preload" href="/test.json" as="fetch">

所有现代浏览器都支持它,如果在几秒钟内没有使用此资源,则会收到警告消息,因为它会对&#34; preload&#34;在这种情况下(延迟,双重负载等)

<link rel="prefetch" ...>的不同之处在于预测未来的导航并且不被广泛支持。

关于此的Chrome插图文章:https://medium.com/reloading/preload-prefetch-and-priorities-in-chrome-776165961bbf

答案 1 :(得分:2)

原来,Chrome中存在使用fetch API与rel=preload here结合使用的错误。我通过使用XMLHttpRequest来解决这个问题。

即使它似乎已经在Chrome 62中得到修复,但我仍然可以在Chrome 63上重现这一点。

答案 2 :(得分:2)

如果您遇到与我相同的问题,您的回复可能与Vary: Accept一起发送,预加载请求随Accept: */*一起发送,而fetch / xhr请求正在{{1} }}

似乎无法更改预加载Accept: application/json行为(叹气),因此您必须删除Accept:,或者使用匹配的{{进行fetch / xhr请求1}}标题。

答案 3 :(得分:1)

您不仅需要添加as =“ fetch”,还必须添加(based on this comment)crossorigin =“ anonymous”。这应该起作用:

<link rel="preload" href="/test.json" as="fetch" crossorigin="anonymous">

答案 4 :(得分:0)

HTML链接元素

浏览器兼容性桌面(2017年6月)

Feature            Chrome   Edge    Firefox (Gecko) Internet Explorer   Opera   Safari
prefetch attribute  56        ?        ?                 ?               43      ?

https://developer.mozilla.org/en/docs/Web/HTML/Element/link

答案 5 :(得分:0)

我对https://w3c.github.io/preload/#as-attribute的允许值进行了许多尝试,但对我来说,正确获取JSON数据的唯一方法是完全删除typeas指令并依赖浏览器找出来。在最新的Chrome浏览器中可以使用,但我认为它可能会随着浏览器行为的改变而改变。

Developer tools image showing XHR push

答案 6 :(得分:0)

根据评论中提到的Chrome bug,如果您拥有preload,则responseType = 'blob'不起作用。

解决方法是设置responseType = 'arraybuffer',然后在onload中使用var blob = new Blob([xhr.response], {type: xhr.getResponseHeader("Content-Type")});手动将其转换为blob

答案 7 :(得分:0)

这是在Chrome和Safari中都可以使用的方法。

<link rel="preload" as="fetch" href="/data.json">
fetch('/data.json', {
    method: 'GET',
    credentials: 'include',
    mode: 'no-cors',
})

此答案包含更多详细信息,并说明其工作原理以及工作原理https://stackoverflow.com/a/63814972/1387163

答案 8 :(得分:-1)

试试as="xhr"。当我进行服务器推送时,似乎在Chrome中为我工作 - 这与HTML标签不完全相同,但如果您通过Ajax / XmlHttpRequest获取该资源,则可能会解决此问题。

答案 9 :(得分:-1)

尝试as="object"。似乎为我工作:

<link rel="preload" href="/test.json" as="object">