• notice
  • Congratulations on the launch of the Sought Tech site

Make HTML5 APP work offline

When your web browser is tied to your desktop, you never lose an Internet connection at any time.

With the ability to access the web on mobile devices significantly improved—first on laptops, then phones, and now tablets, it’s now easier to access your data and apps no matter where you are program. Or is it?

This article was written on the train from London to Liverpool. The train has Wifi and I have a 3G data card, but I'm still not fully connected. Also, many online tools today do not handle this intermediate connection state properly.

So how do we solve this problem? It's not easy, but there are steps you can take today to make your app available to your users wherever they are. Some of these steps implement straight-forward solutions in HTML; some require you to implement some logic, all of which will help you build better applications.

cache your resources

Users are conditionally not entering the URL when they are not online because they know they will get an error page. But it doesn't have to be like this. Build applications that can be loaded even without an Internet connection.

You should build your app to present a consistent UI to your users so that even if they are offline, they can still see and use some of your apps. This will allow you to detect the presence of a network connection and notify users of your application's connection requirements in a graceful, friendly way.

Following our AppCache tutorial , you will find it easy to apply it to an existing application. Your app will contain a link to a manifest file that will contain all the files that contain your app.

CACHE:/js/logic.js/js/options.js/images/loading.png/css/main.css

The browser then ensures that these assets are cached offline until the next update of the manifest file.

Check network connection

Now that you can have your application load and present a consistent interface to your users even when you are offline, you need to detect when there is an internet connection. This is especially important if your application requires an Internet connection to function properly.

HTML5 defines an event that signals when your application connects. This is the easiest way, but not all browsers support it. Nor is it guaranteed to be accurate. Most implementations of the API monitor local network interfaces for changes to determine if your application is online. But what if your network interface is up but your router is down? Are you offline or online?

It's easy to check if you're online by querying window.navigator.onLine

if (navigator.onLine) {
  alert('online')} else {
  alert('offline');}

You can also be told when there is a change in the network state. Just listen for the for the events on window.onOnline and window.onOffline

window.addEventListener("offline", function(e) {
  alert("offline");}, false);window.addEventListener("online", function(e) {
  alert("online");}, false);

The API is straightforward, how do you get it to work if the API isn't implemented in the browser?

It is possible to use a couple more signals to detect if you are offline including side-effects of the AppCache and listening to the responses from XMLHttpRequest.

AppCache error events

The AppCache system always tries to request a manifest to check if it needs to update its asset list. If that request fails, it's usually one of two things, either the manifest file is no longer in use (ie, it's not hosted) or the system doesn't have network access to get the file.

window.applicationCache.addEventListener("error", function(e) {
  alert("Error fetching manifest: a good chance we are offline");});

Failure to detect this request is a good indicator of whether you have a network connection.

XMLHttpRequest

During the use of your application, the network connection may fail, so how do you detect it?

A large number of applications built today use XMLHttpRequest to fetch data from the server while keeping the user within the page. XMLHttpRequest defines events when an error occurs on the network. You can use this to determine if you have a network connection.

Once you've built your application to handle these errors, you can interact with the localStorage methods to store and retrieve cached data in the event of a network failure.

The following code is a good example of a get function capable of responding to network failures.

var fetch = function(url, callback) {
  var xhr = new XMLHttpRequest();
  var noResponseTimer = setTimeout(function() {
    xhr.abort();
    if (!!localStorage[url]) {
      // We have some data cached, return that to the callback.
      callback(localStorage[url]);
      return;
    }
  }, maxWaitTime);
  xhr.onreadystatechange = function() {
    if (xhr.readyState != 4) {
      return;
    }
    if (xhr.status == 200) {
      clearTimeout(noResponseTimer);
      // Save the data to local storage
      localStorage[url] = xhr.responseText;
      // call the handler
      callback(xhr.responseText);
    }
    else {
      // There is an error of some kind, use our cached copy (if available).
      if (!!localStorage[url]) {
        // We have some data cached, return that to the callback.
        callback(localStorage[url]);
        return;
      }
    }
  };
  xhr.open("GET", url);
  xhr.send();};

Monitoring for this error event is easy enough, but passing the result out as a return value can quickly become cumbersome and error-prone. Fortunately, the HTML DOM has a rich event mechanism that you can use to create custom offline/online events.

var fireEvent = function(name, data) {
  var e = document.createEvent("Event");
  e.initEvent(name, true, true);
  e.data = data;
  window.dispatchEvent(e);};

Integrating the fireEvent method into our fetch function allows us to respond to events based on network connectivity and gives us the freedom to build applications independent of monitoring the data returned by the method.

var fetch = function(url, callback) {
  var xhr = new XMLHttpRequest();
  var noResponseTimer = setTimeout(function() {
    xhr.abort();
    fireEvent("connectiontimeout", {});
    if (!!localStorage[url]) {
      // We have some data cached, return that to the callback.
      callback(localStorage[url]);
      return;
    }
  }, maxWaitTime);
  xhr.onreadystatechange = function(e) {
    if (xhr.readyState != 4) {
      return;
    }
    if (xhr.status == 200) {
      fireEvent("goodconnection", {});
      clearTimeout(noResponseTimer);
      // Save the data to local storage
      localStorage[url] = xhr.responseText;
      // call the handler
      callback(xhr.responseText);
    } else {
      fireEvent("connectionerror", {});
      // There is an error of some kind, use our cached copy (if available).
      if (!!localStorage[url]) {
        // We have some data cached, return that to the callback.
        callback(localStorage[url]);
        return;
      }
    }
  };
  xhr.open("GET", url);
  xhr.send();};

We can now build applications that will be notified when something goes wrong somewhere in the network.

window.addEventListener("connectionerror", function(e) {
  alert("There is a connection error");});

Check network status regularly

Using the exact same structure as we did in the XML Http Request example, files on the network can be periodically checked to see if there is a network connection.

setTimeout(function() { fetch("favicon.ico"); } , 30000);

Use it sparingly. If your service is popular, this may increase traffic.

Caching Your Assets Part II: Bootstrapping

A common misconception about AppCache is the belief that all of an application's logic and assets must be cached in order for it to function offline. This is not the case. You can bootstrap your application into a state where it can present the user interface to the user, and load the rest of the information at runtime.

Let's look at a simple example:

-- index.html --<html manifest="cache.manifest">-- cache.manifest --CACHE:/js/logic.js/js/options.js/images/loading.png/css/main.cssNETWORK:*

It is very similar to the AppCache example in Chapter 1, but note the inclusion of the "NETWORK:" section. Every request for data that is not in the CACHE section will be allowed into the network.

With this very simple approach, we can provide a minimal amount of assets to get the application running, and then once we detect that the page has loaded, we can use the loaded JavaScript to bring in the next set of more fully defined assets for the application.

Script loaders have gained acceptance in the web development community as a way to load scripts and other targets for specific standards. For example, if your browser doesn't support any client-side storage, then why load all this extra code?

Integrating the script loader into your project, combined with our offline support testing, allows you to build applications that delight your users. Below is an example using the YepNope JavaScript framework.

yepnope({
  test : isOnline,
  yep  : ['normal.js', 'controller.js', 'assets.js'],
  nope : 'errors.js'});

The above example is a bit contrived, but you can see that given the knowledge of the connection state, you can easily start loading more applications at runtime, and, if loaded offline, can handle different sets of scripts that fail in the case.

cache your data

We dropped it in the previous example "get" request.

In order for your application to be useful, you must cache the data your application uses on the client side. We do this by leveraging the simplicity of the localStorage API.

Every request made by the XMLHttpRequest framework may succeed or fail. If successful, we store the result of the response based on the URL. If it fails, we check localStorage for the requested URL, and if there is data, we return that data.

if (xhr.status == 200) {
  clearTimeout(noResponseTimer);
  // Save the data to local storage
  localStorage[url] = xhr.responseText;
  // call the handler
  callback(xhr.responseText);}else {
  // There is an error of some kind, use our cached copy (if available).
  if (!!localStorage[url]) {
    // We have some data cached, return that to the callback.
    callback(localStorage[url]);
    return;
  }}

Further reading

HTML5Rocks has many tutorials on offline techniques where you can get hands-on with code samples.


Tags

Technical otaku

Sought technology together

Related Topic

1 Comments

author

atorvastatin 80mg usa & lt;a href="https://lipiws.top/"& gt;order lipitor for sale& lt;/a& gt; atorvastatin 20mg sale

Kubfwi

2024-03-09

Leave a Reply

+