Can link rel=preload be made to work with fetch?

后端 未结 3 1039
别跟我提以往
别跟我提以往 2021-01-02 23:09

I have a large JSON blob I would like to have preloaded with my webpage. To do this, I have added

相关标签:
3条回答
  • 2021-01-02 23:25

    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.

    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">
    

    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',
    })
    

    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).

    Here is what I have tried:

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

    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">
    fetch('/data.json', {
        method: 'GET',
        credentials: 'include',
        mode: '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.

    0 讨论(0)
  • 2021-01-02 23:26

    It looks like this is a difference between Safari and Chrome. Safari posts the warning to console, but Chrome does not, so maybe adding crossorigin to the link element does solve the problem, but Safari has some kind of bug?

    0 讨论(0)
  • 2021-01-02 23:32

    Thanks to the discussion in this bug, I got fetch to work with preload in Chromium 67:

    First, add crossorigin attribute to the preload link:

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

    Second, add same-origin credentials to the fetch request:

    fetch(url, {credentials: 'same-origin'}).then(response => {
        console.log(response);
    });
    

    Alternatively, you can use XMLHttpRequest instead of fetch (with XHR you don't need to add anything to the request), but only if you're not going to use responseType = 'blob' - it won't work due to another bug.

    0 讨论(0)
提交回复
热议问题