title: Service Worker FechtEvent.respondWith response is null on iOS 12.1 Safari
body: <p>I can download the website using the service Worker on Android Chrome, macOS Chrome as well as Safari and on Windows Chrome for offline use. When I try to download the website to <strong>iOS 12.1 Safari</strong> it works first. But when I close Safari, go offline and reopen Safari, I get the following <strong>error message</strong>:</p>
  <blockquote>
  <p>Safari can't open the Site.</p>
  <p>Error: &quot;FetchEvent.respondWith received an error: TypeError: There
  seems to be no connection to the Internet.&quot;</p>
  <p>==== AND in the console ====</p>
  <p>FetchEvent.respondWith received an error: Returned response is null</p>
  </blockquote>
  <p>Below you can see the scripts in text form. Unfortunately, I can hardly report anything about the problem, because I don't understand it and hope for some knowledgeable people :)</p>
  <p>index.html</p>
  <pre><code>&lt;!DOCTYPE html&gt;
  &lt;html lang=&quot;en&quot;&gt;
  &lt;head&gt;
      &lt;meta charset=&quot;UTF-8&quot;&gt;
      &lt;title&gt;Title&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
  &lt;h1&gt;Offline App&lt;/h1&gt;
  &lt;/body&gt;
  &lt;script&gt;
      if('serviceWorker' in navigator) {
          navigator.serviceWorker.register('sw.js').then(function (registration) {
              console.log('Service Worker Registered');
          });
      }
  &lt;/script&gt;
  &lt;/html&gt;
  </code></pre>
  <p>sw.js</p>
  <pre><code>/*
   Copyright 2014 Google Inc. All Rights Reserved.
   Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at
   http://www.apache.org/licenses/LICENSE-2.0
   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an &quot;AS IS&quot; BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
  */
  
  importScripts('cache-polyfill.js');
  
  var CACHE_VERSION = 1;
  var CURRENT_CACHES = {
      prefetch: 'prefetch-cache-v' + CACHE_VERSION
  };
  
  self.addEventListener('install', function(event) {
      var now = Date.now();
  
      var urlsToPrefetch = [
          '/pwa/index.html'
      ];
  
      console.log('Handling install event. Resources to prefetch:', urlsToPrefetch);
  
      event.waitUntil(
          caches.open(CURRENT_CACHES.prefetch).then(function(cache) {
              var cachePromises = urlsToPrefetch.map(function(urlToPrefetch) {
                  var url = new URL(urlToPrefetch, location.href);
                  url.search += (url.search ? '&amp;' : '?') + 'cache-bust=' + now;
  
                  var request = new Request(url, {mode: 'no-cors'});
                  return fetch(request).then(function(response) {
                      if (response.status &gt;= 400) {
                          throw new Error('request for ' + urlToPrefetch +
                              ' failed with status ' + response.statusText);
                      }
  
                      return cache.put(urlToPrefetch, response);
                  }).catch(function(error) {
                      console.error('Not caching ' + urlToPrefetch + ' due to ' + error);
                  });
              });
  
              return Promise.all(cachePromises).then(function() {
                  console.log('Pre-fetching complete.');
              });
          }).catch(function(error) {
              console.error('Pre-fetching failed:', error);
          })
      );
  });
  
  self.addEventListener('activate', function(event) {
      var expectedCacheNames = Object.keys(CURRENT_CACHES).map(function(key) {
          return CURRENT_CACHES[key];
      });
  
      event.waitUntil(
          caches.keys().then(function(cacheNames) {
              return Promise.all(
                  cacheNames.map(function(cacheName) {
                      if (expectedCacheNames.indexOf(cacheName) === -1) {
                          console.log('Deleting out of date cache:', cacheName);
                          return caches.delete(cacheName);
                      }
                  })
              );
          })
      );
  });
  
  self.addEventListener('fetch', function(event) {
      if (!navigator.onLine) {
  
          event.respondWith(
              caches.match(event.request).then(function (response) {
                  if (response) {
  
                      return response;
                  }
  
                  console.log('No response found in cache. About to fetch from network...');
  
                  return fetch(event.request).then(function (response) {
                      console.log('Response from network is:', response);
  
                      return response;
                  }).catch(function (error) {
                      console.error('Fetching failed:', error);
                      throw error;
                  });
              })
          );
      }
  });
  </code></pre>