可以使链接 rel=preload 与 fetch 一起使用吗? [英] Can link rel=preload be made to work with fetch?

查看:14
本文介绍了可以使链接 rel=preload 与 fetch 一起使用吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个大的 JSON blob,我想在我的网页中预加载.为此,我已将 <link rel="preload" as="fetch" href="/blob.json"> 添加到我的页面.我也有一个 JS 请求来获取相同的 blob.

I have a large JSON blob I would like to have preloaded with my webpage. To do this, I have added <link rel="preload" as="fetch" href="/blob.json"> to my page. I also have a JS request to fetch the same blob.

这不起作用,控制台报告:

This does not work, and the console reports:

[警告] 资源 blob.json 已使用链接预加载进行预加载,但在窗口加载事件后的几秒钟内未使用.请确保它不是无缘无故预加载的.

[Warning] The resource blob.json was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it wasn't preloaded for nothing.

MDN 声称这可以通过添加 crossorigin 到链接标签.AFAICT,这不是真的,没有组合或跨域属性实际上可以使它起作用.

MDN claims that this can be fixed by adding crossorigin to the link tag. AFAICT, this is not true, and no combination or crossorigin attributes will actually make it work.

使用开发人员控制台中的 copy-as-curl 命令,似乎没有链接标记和属性的组合会发出与 JS 中的 fetch/XHR 调用相同的请求.

Using the copy-as-curl command from the developer console, it seems like there is no combination of link tag plus attributes that will issue the same request as a fetch/XHR call in JS.

我很想在这件事上犯错.

I would love to be wrong about this.

推荐答案

这是一个在 Chrome 和 Safari 中都可以使用并支持 cookie 的预加载 fetch 的工作解决方案.

Here is the working solution to preload fetch that works both in Chrome and Safari and supports cookies.

不幸的是,它仅适用于相同的域请求.

Unfortunately, it works only for the same domain requests.

首先,不要为 preload 标签指定 crossorigin 属性,这将确保 Safari 以 no-cors 模式发送请求并包含 cookie

First, do not specify crossorigin attribute for preload tag, this will ensure Safari will send request in no-cors mode and include cookies

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

其次,fetch api 请求也应该在 no-cors 模式下完成,并包含凭据(cookies).注意这个请求不能有任何自定义的headers(如AcceptContent-Type等),否则浏览器将无法匹配这个请求和预加载的headers.

Second, the fetch api request should also be done in no-cors mode and include credentials (cookies). Pay attention that this request cannot have any custom headers (like Accept, Content-Type, etc), otherwise the browser won't be able to match this request with preloaded one.

fetch('/data.json', {
    method: 'GET',
    credentials: 'include',
    mode: 'no-cors',
})

我尝试了 crossorigin 属性值和 fetch API 配置的其他组合,但它们在 Safari 中都不适合我(仅在 Chrome 中).

I have tried other combinations of crossorigin attribute value and fetch API configuration, but none of them worked for me in Safari (only in Chrome).

这是我尝试过的:

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

<script>
fetch('/data.json', {
    method: 'GET',
    credentials: 'same-origin',
    mode: 'cors',
})
</script>

上述方法在 Chrome 中有效,但在 Safari 中无效,因为 Safari 中的预加载请求不会发送 cookie.

The above works in Chrome, but not in Safari, because cookies are not sent by preload request in Safari.

<link rel="preload" as="fetch" href="/data.json" crossorigin="use-credentials">

<script>
fetch('/data.json', {
    method: 'GET',
    credentials: 'include',
    mode: 'cors',
})
</script>

以上内容在 Chrome 中有效,但在 Safari 中无效.虽然 cookie 是通过 preload 请求发送的,但 Safari 无法匹配 fetch 和 preload 请求,可能是因为 cors 模式不同.

The above works in Chrome but not in Safari. Though cookies are sent by preload request, Safari is not able to match fetch with preload request probably because of the different cors mode.

这篇关于可以使链接 rel=preload 与 fetch 一起使用吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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