PWA 程序開發實踐 原 薦

本文開源實驗室原創,轉載請以鏈接形式註明地址:https://kymjs.com/code/2017/02/18/01

題外話:寫給所有移動端開發的同學:PWA(Progressive Web Apps) 一定是將來的移動開發趨勢,且學且珍惜。
手機端可在我公衆號【技術實驗室】的歷史推送文章查看。

已經公開章節:
第一篇 · Service Worker:讓網頁無網絡也能訪問
第二篇 · PWA 程序開發實踐
GitHub 演示項目 · PWAblog

介紹

這裏再介紹一下 Progressive Web Apps 是結合了 web 和 原生應用中某些功能的一種體驗(本質上還是 web 應用)。但是作爲一個 web 應用,它可以 斷網使用推送消息發送通知從桌面啓動,當然還包括 Web 應用的優勢:免安裝快速開發依賴瀏覽器跨平臺(支持包括Edge在內的各種主流PC/手機瀏覽器)

fetch 攔截請求

之前講述了 PWA 最重要的組件:Service Worker,沒有看過的可以先看看:https://kymjs.com/code/2017/02/04/01/。今天繼續來看他的一些高級屬性。
今天要說的高級屬性已經寫在了我的Service Worker裏,可查看:開源實驗室防盜鏈fetch事件。
fetch是一個很有意思的事件,它可以攔截一個網絡請求數據,決定是從緩存返回還是去網絡請求。

self.addEventListener('fetch', function(e) {
  var allDataUrl = filesToCache;
  var requestIsDataApi = false;

  for (dataurl in allDataUrl){
    if (e.request.url.indexOf(dataurl) > -1 ) {
      requestIsDataApi = true;
      e.respondWith(
        caches.open(dataCacheName).then(function(cache) {
          return fetch(e.request).then(function(response){
            cache.put(e.request.url, response.clone());
            return response;
          });
        })
      );
      break;
    }
  }

  if (!requestIsDataApi){
    e.respondWith(
        caches.match(e.request).then(function(response) {
          return response || fetch(e.request);
        })
      );
  }
});

這裏,我將所有請求的 URL 做了個判斷,如果是緩存URL,直接從本地緩存中返回;反之如果是不屬於緩存 URL,就攔截請求,使用fetch()發請求,將結果保存到緩存並返回。
可以攔截請求這一點讓fetch事件可以玩出花來,下一篇我們繼續講 PWA 時再看它的黑科技。

應用程序外殼(App Shell)

如果你按照上一篇博客的講述,自己動手實現了博客斷網訪問。在欣喜的同時一定也會發現,博客沒法更新了。
當博客內容更改的時候,如果之前用戶已經訪問過這篇博客,他再次訪問依舊是之前緩存過的內容,而不是新內容。
這就涉及到 PWA 的一個名詞:應用程序外殼(App Shell)
一個 web 應用分爲 應用程序外殼應用數據, 應用外殼的結構分爲應用的核心基礎組件和承載數據的 UI。所有的 UI 和基礎組件都使用一個 service worker 緩存在本地,因此在後續的加載中 Progressive Web App 僅需要加載需要的數據,而不是加載所有的內容。
這就類似 Android 應用,下載安裝的是外殼,只需要下載一次,接口API請求的數據是實時變化的。
因此,之前我們是把整個博客當成了APP Shell,除非版本變更,否則當然不會再發生變化。

設計 App Shell

還是以 開源實驗室 來做例子,首先看看效果圖。

開源實驗室PWA

一個移動應用,應該是包括 ActionBar(StatusBar)ContentBottomBar(FooterBar)三部分構成。ActionBar 和 BottomBar 基本是固定的不會有大變化,這部分用 html 很容易實現,最主要的是 Content 部分,這部分內容是動態改變的,不包括在 App Shell 中,因此這裏我們先不管他。

<!DOCTYPE html>
<html>
<head>
  <title>開源實驗室-kymjs張濤</title>
  <link rel="stylesheet" type="text/css" href="styles/inline.css">  
</head>
<body>

  <header class="header">
    <h1 class="header_title">開源實驗室</h1>
    <a href="https://kymjs.com/about"><button id="butAbout" class="headerButton" aria-label="about"></button></a>
  </header>

  <main class="main">
  </main>
 
  <footer class="footer">
   <button id="column1" class="button1">專欄</button>
   <button id="column2" class="button2 active">博客</button> 
   <button id="column3" class="button3">作品</button> 
  </footer>

  <script src="scripts/app.js" async></script>
</body>
</html>

APP Shell 已經完成了,接下來我們需要在 service-worker 中聲明他是一個不需要多次下載的頁面。

設計 Content

由於 Content 是變化的,所以我們只寫一個模板,讓 js 去根據數據改變這個模板內容。
先寫好將會放在 Content 區域的 item 模板(相當於 Android 中 ListView 的 item 先創建一個模板)。

<div class="post-list-body post-area"> 
  <div class="list-item" hidden>
    <a href="http://kymjs.com/" id="blogLink">
      <div class="post-list-item">
        <font color="#aaaaaa" id="blogTime"></font>
    	 <h2><font color="#AE57A4" id="tag"></font>
    	 <font color="#333333" id="title"></font></h2>
        <p><font color="#666666" id="description"> description template </font></p>
      </div>
    </a>
  </div>
</div>

接着使用 AJAX 請求博客的內容數據,可以通過調用開源實驗室的 OpenAPI 獲取數據。

app.requestBlogList = function(){
	 //跨域請求會失敗,本地調試時先使用僞數據
	 // var url = "/download.json";
    var url = "http://openapi.kymjs.com/oslab";
    
    xmlhttp.onreadystatechange=function(){
    if (xmlhttp.readyState == XMLHttpRequest.DONE && xmlhttp.status==200){
        var response = JSON.parse(xmlhttp.response);
        var itemList = response.item;
        app.addContent(itemList);        
      }
    };
    xmlhttp.open("GET", url);
    xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;"); 
    xmlhttp.send();
  }

拿到數據了以後,調用addContent(),去根據模板動態生成內容。代碼就不貼了,具體可查看 github 倉庫 PWAblog

配置 Service Worker

至此,整個應用就已經全部開發完成了,接下來我們只需要配置 service worker 讓應用程序外殼生效就 OK 了。
回顧上一篇文章,首先在 js 中判斷瀏覽器是否支持,如果支持就註冊。
監聽 install 事件,緩存 url。
監聽 activate事件,移除過期緩存,保證應用更新版本後可以升級。
最後,通過fetch事件攔截網絡請求做訪問緩存邏輯處理。
這樣一個簡單的 PWA 程序就完成了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章