Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
465 views
in Technique[技术] by (71.8m points)

javascript - Only in Chrome (Service Worker): '... a redirected response was used for a request whose redirect mode is not "follow" '

When I refresh (or go offline) in Chrome then I get "This site can't be reached" and the following logged to console: The FetchEvent for "http://localhost:8111/survey/174/deployment/193/answer/offline/attendee/240/" resulted in a network error response: a redirected response was used for a request whose redirect mode is not "follow".. When I refresh in Firefox everything works fine. Could someone explain why this is happening?

Here is my simplified SW.

importScripts("/static/js/libs/idb.js")

var CACHE_NAME = "upshot-cache-version3"
var urlsToCache = [...]

self.addEventListener("install", event => {
  event.waitUntil(
    caches
      .open(CACHE_NAME)
      .then(cache => {
        urlsToCache.map(url => cache.add(url))
      })
  )
})

self.addEventListener("activate", event => {
  clients.claim()
})

self.addEventListener('fetch', event => {
  event.respondWith(
    caches
      .match(event.request)
      .then(response => {

        if (response) {
          return response
        }

        var fetchRequest = event.request.clone()

        return fetch(fetchRequest).then(response => {
          if (!response || response.status !== 200 || response.type !== 'basic') {
            return response
          }
          var responseToCache = response.clone()
          caches.open(CACHE_NAME).then(cache => cache.put(event.request, responseToCache))
          return response
        })

      })
  )
})
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

This is due to a (relatively) recent change in the security restrictions around what kind of responses can be used to satisfy navigations. It should apply to all browsers that support service workers (i.e. both Chrome and Firefox today), but it's possible that you're testing with a version of Firefox that's out of date.

The background on what changed can be found in this issue tracker entry, and there's also more background on the decision that led to the underlying specification.

In terms of modifying your service worker to handle the security restriction, if you're currently responding to navigation requests for certain URLs with a HTTP 30x redirect to a different URL, you'll need to take care not to just store that redirected response directly in the cache.

You can tell whether a given response was redirected by checking whether response.redirected is true, and if so, use code along the lines of this (adapted from the Workbox project) to create a "clean" copy of the response that could then be stored in the cache:

function cleanResponse(response) {
  const clonedResponse = response.clone();

  // Not all browsers support the Response.body stream, so fall back to reading
  // the entire body into memory as a blob.
  const bodyPromise = 'body' in clonedResponse ?
    Promise.resolve(clonedResponse.body) :
    clonedResponse.blob();

  return bodyPromise.then((body) => {
    // new Response() is happy when passed either a stream or a Blob.
    return new Response(body, {
      headers: clonedResponse.headers,
      status: clonedResponse.status,
      statusText: clonedResponse.statusText,
    });
  });
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...