在iOS 12.1 Safari上,服务工作者FechtEvent.respondWith响应为空

时间:2018-11-22 12:36:23

标签: ios safari service-worker

我可以在Android Chrome,macOS Chrome,Safari和Windows Chrome上使用“工作者”服务下载网站,以供离线使用。当我尝试将网站下载到 iOS 12.1 Safari 时,它将首先运行。但是,当我关闭Safari,脱机并重新打开Safari时,会收到以下错误消息

  

Safari无法打开网站。

     

错误:“ FetchEvent.respondWith收到错误:TypeError:存在   似乎与互联网没有任何联系。”

     

====控制台中的AND ====

     

FetchEvent.respondWith收到错误:返回的响应为空

在下面,您可以以文本形式查看脚本。不幸的是,我几乎无法报告任何有关该问题的信息,因为我不理解它,希望有一些知识渊博的人:)

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>Offline App</h1>
</body>
<script>
    if('serviceWorker' in navigator) {
        navigator.serviceWorker.register('sw.js').then(function (registration) {
            console.log('Service Worker Registered');
        });
    }
</script>
</html>

sw.js

/*
 Copyright 2014 Google Inc. All Rights Reserved.
 Licensed under the Apache License, Version 2.0 (the "License");
 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 "AS IS" 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 ? '&' : '?') + 'cache-bust=' + now;

                var request = new Request(url, {mode: 'no-cors'});
                return fetch(request).then(function(response) {
                    if (response.status >= 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;
                });
            })
        );
    }
});

2 个答案:

答案 0 :(得分:0)

对不起,我还没有答案,但是我的Web应用程序遇到了完全相同的问题,并且花了几个小时在上面。因此,我想将所有发现发表在这里。

检查Web应用程序是否可以在iOS 12中脱机工作的步骤

  1. 使用Safari(iOS 12或12.1)访问网站
  2. 关闭Safari中的“网站”标签
  3. 在iPhone上按“主页”按钮可将Safari设置为背景
  4. 按下iPhone电源按钮以关闭屏幕
  5. 再次按下iPhone电源按钮以唤醒手机
  6. 关闭iPhone控制中心的所有网络连接(WiFi和蜂窝网络)
  7. 打开Safari,再次访问网站->它应在离线模式下工作。

iOS 12与iOS 11.3

似乎此问题是从iOS 12引入的。我的Web应用程序(https://viewsbyme.com)在iOS 11.3上可以完美离线运行,在该版本中,移动Safari版本首次引入了Service Worker,但得到了iOS 12和iOS 12.1的响应。离线时:

Safari无法打开页面。错误为:“ FetchEvent.respondWith收到错误:TypeError:Internet连接似乎处于脱机状态。”。

不确定它是否与此错误报告相关(它显示为“已修复”,但如果向下滚动到线程底部,实际上还没有):

https://bugs.webkit.org/show_bug.cgi?id=190269

工作和不工作的Web应用示例

例如,这两个PWA可以在iOS 12中脱机工作:

https://simpleoffline.website

https://www.currency-calc.com

这两个PWA在iOS 12中无法离线工作(但在其他平台的Chrome上可以完美运行):

https://2048-opera-pwa.surge.sh

https://voice-memos.appspot.com

通过比较这些PWA之间的Service Worker脚本并找出是什么使它们起作用与不起作用,似乎很简单。但是我还没有弄清楚增量。

答案 1 :(得分:-1)

清除Web缓存后,对我来说工作正常...