渐进式Web应用程序:如何检测和处理连接何时再次启动

时间:2017-06-26 08:59:12

标签: javascript progressive-web-apps offlineapps

使用PWA,我们可以在离线模式下关闭设备连接。但是,我们如何检测固定网络连接并自动重新加载/重新激活应用程序?

4 个答案:

答案 0 :(得分:23)

您可以监控offline and online eventswidely supported。此外,您可以尝试从目标服务器URL获取HEAD来测试连接性:

// Test this by running the code snippet below and then
// use the "Offline" checkbox in DevTools Network panel

window.addEventListener('online', handleConnection);
window.addEventListener('offline', handleConnection);

function handleConnection() {
  if (navigator.onLine) {
    isReachable(getServerUrl()).then(function(online) {
      if (online) {
        // handle online status
        console.log('online');
      } else {
        console.log('no connectivity');
      }
    });
  } else {
    // handle offline status
    console.log('offline');
  }
}

function isReachable(url) {
  /**
   * Note: fetch() still "succeeds" for 404s on subdirectories,
   * which is ok when only testing for domain reachability.
   *
   * Example:
   *   https://google.com/noexist does not throw
   *   https://noexist.com/noexist does throw
   */
  return fetch(url, { method: 'HEAD', mode: 'no-cors' })
    .then(function(resp) {
      return resp && (resp.ok || resp.type === 'opaque');
    })
    .catch(function(err) {
      console.warn('[conn test failure]:', err);
    });
}

function getServerUrl() {
  return document.getElementById('serverUrl').value || window.location.origin;
}
<fieldset>
  <label>
    <span>Server URL for connectivity test:</span>
    <input id="serverUrl" style="width: 100%">
  </label>
</fieldset>
<script>document.getElementById('serverUrl').value = window.location.origin;</script>

<p>
  <i>Use Network Panel in DevTools to toggle Offline status</i>
</p>

一个technique处理此问题:

  • 离线事件

    • 显示离线图标/状态
    • 仅启用可离线使用的功能(通过缓存数据)
  • 在线活动

    • 显示在线图标/状态
    • 启用所有功能

答案 1 :(得分:11)

请注意online事件,该事件仅告知设备是否已连接。它可以连接到WiFi热点而无需实际的Internet连接(例如,因为凭据)。

答案 2 :(得分:2)

PWA的一个常见做法是遵循Application Shell方法来处理您的应用程序。这将允许您在进入时缓存Application Shell,然后根据连接加载数据。

此方法中缓存和服务的最常用方法是从具有回退到网络的缓存提供服务,无论何时请求的资源在缓存中不可用,您都可以通过网络发送请求并缓存响应。然后从缓存中提供服务。

当你在一个不稳定的连接上时,例如在火车上,这可以让你更加优雅地降级。

实施此目的的一个例子:

const cacheName = "my-cache-v1"

self.addEventListener('fetch', (event) => {
  if (event.request.method === 'GET') {
    event.respondWith(
      caches.match(event.request).then((response) => {
        if (response) {
          return response;
        }
        return fetch(event.request).then((response) => {
          return caches.open(cacheName).then((cache) => {
            cache.put(event.request.url, response.clone());
            return response;
          });
        });
      })
    );
  }
});

在上面的示例中(Service Worker生命周期中只有一个必需步骤),您还需要删除过期的缓存条目。

答案 3 :(得分:1)

我见过的大多数服务都使用以下做法:增加到某个值超时,尝试联系服务器。达到最大超时值时,会出现带有手动recconect按钮的指示器,指示下次重新连接尝试的次数