【问题标题】:Only in Chrome (Service Worker): '... a redirected response was used for a request whose redirect mode is not "follow" '仅在 Chrome(Service Worker)中:'...重定向响应用于重定向模式不是“follow”的请求'
【发布时间】:2017-08-01 22:24:02
【问题描述】:

当我在 Chrome 中刷新(或离线)时,我会收到“无法访问此站点”并将以下内容记录到控制台: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".。当我在 Firefox 中刷新时,一切正常。有人可以解释为什么会这样吗?

这是我的简化版。

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

      })
  )
})

【问题讨论】:

    标签: javascript google-chrome service-worker fetch-api


    【解决方案1】:

    这是由于最近(相对)安全限制发生了变化,围绕可以使用哪种响应来满足导航要求。它应该适用于所有支持 Service Worker 的浏览器(即现在的 Chrome 和 Firefox),但您可能正在使用过期的 Firefox 版本进行测试。

    可以在此issue tracker entry 中找到有关更改的背景,还有more background 说明导致基础规范的决定。

    在修改 Service Worker 以处理安全限制方面,如果您当前使用 HTTP 30x 重定向到其他 URL 来响应某些 URL 的导航请求,则需要注意不要只存储该 URL直接在缓存中重定向响应。

    您可以通过检查 response.redirected 是否为 true 来判断给定的响应是否被重定向,如果是,则使用与此类似的代码(改编自 Workbox 项目)创建一个“干净”副本然后可以存储在缓存中的响应:

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

    【讨论】:

    • 感谢详细回复,Firefox版本其实是55.0b13(开发者版)。
    • 嗯......不知道为什么你会看到不同的行为,在这种情况下。 bugzilla.mozilla.org/show_bug.cgi?id=1243792 是 Firefox 实现跟踪错误,那里的工作已经完成。
    • 在实现这一点时,我们看到文件是单独下载而不是在页面上呈现。例如,当响应返回时,.html 模板不会加载到页面上,而是发送到我们的下载文件夹。这似乎是由于 MIME 类型是八位字节/流。有没有人遇到过类似的情况?
    猜你喜欢
    • 1970-01-01
    • 2019-08-11
    • 2018-09-28
    • 1970-01-01
    • 2015-08-31
    • 2016-09-17
    • 2011-01-29
    • 2020-09-04
    • 1970-01-01
    相关资源
    最近更新 更多