We're looking for a user researcher to understand the needs of developers and designers. Is this you or someone you know? Check out the post: https://mzl.la/2IGzdXS

这篇翻译不完整。请帮忙从英语翻译这篇文章

在离线状态下开放Web应用功能是一个重要的问题:用户在移动中可能会丢失网络。 此外,让您的文件在本地可用,将使您的应用程序需要更少的服务器访问,因此更具响应能力。

本文提供了有关使应用程序脱机工作的建议,以及常见问题解答,示例以及底层的进一步阅读,以供任何需要详细了解所涉及技术(包括IndexedDB,localStorage,Application Cache, XMLHttpRequest等。

离线工作流程

下图说明了离线应用程序的典型工作流程。 入口点是当应用程序被下载/安装,然后启动 - 导航到在线Web应用程序的情况下,安装和打开的情况下,可安装的应用程序(例如在Firefox OS上)。在这一点上的标准行为 应该是将应用程序的资产和初始数据集存储在设备上,如果可能的话,应用程序可以被使用,离线存储其数据集并定期与服务器上的数据集同步。

For future running of the app, the app should try to detect whether it is online or not. If it is, it should sync with the server and download new data and assets. If not, it should continue to use what it has offline.

推荐

The following is a set of recommendations and best practices for getting up and running with offline web apps quickly.

检测离线状态

There are a few APIs available to determine the user's connection status. These are useful because you can skip HTTP requests if you know the user is offline. You can also display less generic failure messages. For example: if you were writing a Twitter client, a message like “New tweets cannot be loaded while offline” is more informative than “Could not make HTTP connection.”

Try to focus on loading data from your/others' API only when needed, and keep data cached so you don't have to request the same data twice. It can also be helpful to prefetch some data so the user can use parts of your app offline that they have yet to open.

The Network information API is designed to detect online status, but this is not very reliable. There are a number of other offline detection mechanisms, but we would recommend using an offline detection library, such as offline.js.

If you are using XMLHttpRequest to update data dynamically, you can check its response to determine if the network connection has dropped during the use of your app. If your app has systemXHR privileges, you can check for a connection to a site unlikely to be down to determine if you have an active connection (iOS does this with Apple.com).

// We'll assume we aren't online.
var online = false;

// Assume we're a packaged app with systemXHR permissions.
// https://developer.mozilla.org/docs/Web/Apps/App_permissions
var request = new window.XMLHttpRequest({mozSystem: true});
request.open('HEAD', 'http://www.mozilla.org/robots.txt', true);
request.timeout = 5750;

request.addEventListener('load', function(event) {
   console.log('We seem to be online!', event);
   online = true;
});

var offlineAlert = function(event) {
   console.log('We are likely offline:', event);
}

request.addEventListener('error', offlineAlert);
request.addEventListener('timeout', offlineAlert);

request.send(null);

When your app is first loaded/installed, it should store its assets and data offline, as indicated below. On subsequent loads, it should take a progressive enhancement approach — assume the app is offline and work with the dataset it has available in offline storage. If online, it should update the assets and data as available.

存储离线资源

If you are distributing your app as a packaged app on the app store (for example a Firefox OS app, distributed via the Firefox Marketplace), then you get this part for free — once the app is installed on the device, the assets are saved locally (see Packaged apps).

If your app is hosted and you want it to be available as an open web app as well as installed on Firefox OS, your options are currently somewhat limited. You could use Application Cache.

The AppCache manifest will typically list of all the CSS, fonts, JavaScript, and image files you use. You can use tools to generate your manifest or create one by hand. This is an example of the format, from Face Value’s manifest:

CACHE MANIFEST
# v 0.1 / 12

CACHE:
css/app.css
img/coins/gold@2x.png
js/main.js
js/lib/require.js

NETWORK:
*
http://*
https://*

Note: If you're using JavaScript templates like mustache, be sure to include your templates in your AppCache manifest or precompile them into your built JavaScript files.

Important: In your AppCache manifest you cannot specify any resources that are on a different domain (even redirects). Chrome lets you do this as long as the resources are served over SSL, but this contravenes the spec, and other browsers don't. Bear this in mind if, for example, you are serving content from a CDN with a different origin.

AppCache问题,以及未来

然而,对于任何不同尺寸和复杂性的应用程序, AppCache是​​一个有问题的解决方案,我们实际上到目前为止会推荐你不要使用它。如果你真的希望资源可以离线使用,​​一个更好的解决方案可能是通过 XMLHttpRequest 获取你的资源,然后将其存储在一个离线数据存储库中, 例如 IndexedDB (见下文)。在不久的将来,Service Workers 将可以准备使用,并为离线资源存储和使用的问题提供了一个更好的解决方案。

离线存储数据

要使用离线数据快速启动并运行,我们建议您使用 localForage, 一个方便的库,可以消除跨浏览器支持离线数据技术的差异。它通过IndexedDB 为支持它的浏览器提供异步数据存储;  然后它回落到 WebSQL支持的浏览器(如Safari), 和 localStorage为浏览器提供更基础的支持。 (见 更详细的支持信息)。

localForage 使用简单, localStorage-类语法, 用于获取和设置数据项 :

localforage.getItem('key', function(value) {
        alert('My value is: ' + value);
    });
}
localforage.setItem('key', 'value', doSomethingElse);

Note: 了解更多信息, 阅读 如何使用 localForage

Note: The Device Storage API is an option available on Firefox OS for storing large data objects, but IndexedDB (localForage) should also be ok. The Podcasts reference app uses IndexedDB to store episodes in its episode model code.

Note: Another good option for offline data storage is dexie.js, a wrapper for IndexedDB that allows fast code development via a nice, simple syntax.

保存状态

During app usage, you should ensure that its state is saved periodically to the offline data store, and save state locally when user closes the app (though IndexedDB does not allow this).

与服务器端同步

你的应用程序也应该将数据定期保存回服务器。If your app is offline you should consider building a queueing solution that can handle a lack of connectivity, aiming to save the updates once the network is available again. We have developed Mozilla Kinto a self-hostable service to let you do that.

可能有帮助的第三方代码:

例子

教程

如果你想了解有关localForage等在幕后工作的更多信息,这些教程将有所帮助。

参考

文档标签和贡献者

此页面的贡献者: varcat, hiyuki, xgqfrms-GitHub
最后编辑者: varcat,