简体   繁体   English

服务工作者打破301重定向

[英]Service Worker breaking 301 redirects

I'm using a service worker on a WordPress site and it's messing up the redirections from https://example.com/page to https://example.com/page/ . 我在WordPress网站上使用服务工作者,它正在搞乱从https://example.com/pagehttps://example.com/page/的重定向。

After the first load, going to the URL without the trailing slash Blink browsers say "This site can't be reached" and Firefox says "Corrupted content error". 第一次加载后,转到没有尾部斜杠的URL Blink浏览器说“无法访问此站点”,Firefox说“内容已损坏”。

Based on my reading of https://medium.com/@boopathi/service-workers-gotchas-44bec65eab3f#.hf3r4pbcs and How to alter the headers of a Request? 基于我对https://medium.com/@boopathi/service-workers-gotchas-44bec65eab3f#.hf3r4pbcs的解读以及如何更改请求的标题? I think I have to detect when a response is 3xx and set the redirect mode to manual. 我必须检测响应是3xx并将重定向模式设置为手动。

However nothing I've tried based on my research has worked. 然而,根据我的研究,我没有尝试过任何事情。 How do I fix this? 我该如何解决?

Current service worker file: 当前服务工作者文件:

var cacheName = 'v14';

var urlsToCache = [
  // list of URLs to precache
];

self.addEventListener('install', event => {

  function onInstall(event) {
    return caches.open(cacheName)
      .then(cache => cache.addAll(urlsToCache));
  }

  event.waitUntil(
    onInstall(event)
      .then(() => self.skipWaiting())
  );

});

self.addEventListener('activate', event => {

  function onActivate (event) {
    return caches.keys()
      .then(cacheKeys => {
        var oldCacheKeys = cacheKeys.filter(key => key.indexOf(cacheName) !== 0);
        var deletePromises = oldCacheKeys.map(oldKey => caches.delete(oldKey));
        return Promise.all(deletePromises);
      })
  }

  event.waitUntil(
    onActivate(event)
      .then(() => self.clients.claim ())
  );
});

self.addEventListener('fetch', event => {

  function onFetch (event) {
    // Let's not interfere with requests for stuff that doesn't need to be cached
    // or could prevent access to admin if it is
    if (event.request.url.match(/wp-admin/) || event.request.url.match(/wp-login/) || event.request.url.match(/preview=true/) || event.request.url.match(/wp-includes/) || event.request.url.match(/plugins/) || event.request.url.match(/google-analytics/) || event.request.url.match(/gravatar\.com/) || event.request.url.match(/login/) || event.request.url.match(/admin/) || event.request.method !== 'GET') {
      return;
    }

    // Determine type of asset
    var request = event.request,
        acceptHeader = request.headers.get('Accept'),
        resourceType = 'static';

    if(acceptHeader.indexOf('text/html') !== -1) {
      resourceType = 'content';
    } else if(acceptHeader.indexOf('image') !== -1) {
      resourceType = 'image';
    }

    // Network first for HTML and images
    if(resourceType === 'content') {
      event.respondWith(fetch(request.url, {
        method: request.method,
        headers: request.headers,
        mode: 'same-origin', // need to set this properly
        credentials: request.credentials,
        redirect: 'manual'
      })
        .then(response => addToCache(request, response)) // read through caching
        .catch(() => fetchFromCache(event))
        .catch(() => offlineResponse(resourceType))
      )
    }

    // Cache first for static assets
    else if(resourceType === 'static' || resourceType === 'image') {
      event.respondWith(fetchFromCache(event)
        .catch(() => fetch(request))
        .then(response => addToCache(request, response))
        .catch(() => offlineResponse(resourceType))
      )
    }
  }

  onFetch(event);

});

function addToCache(request, response) {

  if(response.ok) { // only 200s
    var copy = response.clone(); // Because responses can only be used once
    caches.open(cacheName)
      .then(cache => {
        cache.put(request, copy);
      });

    return response;
  }

}

function fetchFromCache (event) {

  return caches.match(event.request)
    .then(response => {
      if(!response) {
        // A synchronous error that will kick off the catch handler
        throw Error('${event.request.url} not found in cache');
      }
    return response;
  });

}

function offlineResponse (resourceType) {

  if(resourceType === 'content') {
    return caches.match('/offline/');
  }
  return undefined;

}

When encountering error with particular site, I suggest to clear your browser cache and delete your saved cookies for the site first. 当遇到特定网站的错误时,我建议先清除浏览器缓存并删除您保存的网站Cookie。 Corrupted Content Error can be caused by running outdated software in the server. 损坏的内容错误可能是由于在服务器中运行过期的软件引起的。

Things to note about a service worker is that, it is a JavaScript worker . 有关服务工作者的注意事项是,它是一名JavaScript工作者 So, it cant access the DOM directly. 因此,它无法直接访问DOM。 Instead, a service worker can communicate with the pages it controls by responding to messages sent via the postMessage. 相反,服务工作者可以通过响应通过postMessage发送的消息与其控制的页面进行通信。

You don't need to do anything to follow redirects. 您无需执行任何操作来跟踪重定向。 If requesting some/url and being redirected to some/url/ the serviceo worker should be able to get the proper response. 如果请求some/url并被重定向到some/url/ serviceo worker应该能够得到正确的响应。

But if you want to manually handle the 3XX answer you can do: 但是如果你想手动处理3XX答案,你可以这样做:

self.onfetch = function (event) {
  var dontFollowRedirects = new Request(event.request.url, { redirect: 'manual' });
  event.respondWith(fetch(dontFollowRedirects)
    .then(function (response) {
      if (response.status >= 300 && response.status < 400) {
        return doSomethingWithRedirection(response);
      }
    })
  );
}

Try this on a clean state, wiping out your caches and pre-installed Service Workers. 在干净的状态下尝试这个,擦除您的缓存并预先安装Service Worker。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM