__________     __ __     __  _______    ________
  / ____/ __ \   / // /    / / / /  _/ |  / / ____/
 / / __/ / / /  / // /_   / /_/ // / | | / / __/
/ /_/ / /_/ /  /__  __/  / __  // /  | |/ / /___
\____/\____/     /_/    /_/ /_/___/  |___/_____/

 --- A GOPHER-LIKE INTERFACE FOR HIVE BLOCKCHAIN ---

PWA 学习笔记之 fetch API

BY: @semlinker | CREATED: Jan. 13, 2018, 6:08 a.m. | VOTES: 2 | PAYOUT: $0.00 | [ VOTE ]

Progressive Web App (PWA)是渐进增强 Web App,它能让我们在不可靠的网络上也能快速加载、能够接收桌面通知、具有桌面图标,并且可采用顶层全屏体验的方式加载。

[IMAGE: https://steemitimages.com/DQmb6srEawUexZ7jJQrdhDW8mzexSAB4VefxDfvvtxRSqKS/fetch-api.png]

(背景素材来源:Google - progressive-web-apps)

Progressive Web App 具有的以下主要特点:

PWA 基于很多新的 API 和新的技术,如 fetch API、CacheStorage API、Background Sync、Service Worker 和 IndexedDB 等。然而要想真正了解并掌握 PWA,就必须了解它背后基于的技术。因此后续的文章,我们将逐一介绍 PWA 的相关技术。有兴趣的小伙伴们赶紧上车,我们将从 fetch API 开始,开启 PWA 的学习旅程。

fetch 中文的意思为获取,即通过它我们可以用来获取资源。在前端的日常工作中,我们通常需要从 API 获取数据,然后对数据进行处理或展示。在与服务器交互过程中使用的数据格式一般是 JSON,接下来我们先来体验一下,利用 fetch API 获取 angular 项目的团队的前五位成员,实现代码如下:

if("fetch" in this) {
  fetch("https://api.github.com/orgs/angular/members?page=1&per_page=5")
    .then(res => res.json())
    .then(console.dir)
}

要实现同样的功能,我们当然也可以使用 XMLHttpRequest 对象,实现代码如下:

var xhr = new XMLHttpRequest();
xhr.open('GET', "https://api.github.com/orgs/angular/members?page=1&per_page=5");
xhr.responseType = 'json';
xhr.onload = function() {
  console.dir(xhr.response);
};
xhr.send();

是不是感觉使用 fetch 简单很多,然而我们并不能随心所欲的使用它,因为它有兼容性问题,具体如下下图所示 (详细信息可浏览 can i use - fetch):

[IMAGE: https://steemitimages.com/DQmW498ngn2oScq7E3TSL8TtE1Wsusrh784gfs1u99izZ1F/fetch-api.png]

(图片来源:caniuse - fetch)

对于大多数小伙伴来说,应该更熟悉 jQuery.ajax()。fetch 规范与 jQuery.ajax() 的主要区别如下:

除了使用 fetch API 来获取 JSON 数据,我们也可以使用它来获取其它资源,比如普通文本、图片资源等。下面我们来看一下如何使用 fetch API 来获取图片资源,并在页面中显示。

if ("fetch" in this) {
  let myImage = document.querySelector('img');
  fetch('https://mdn.github.io/dom-examples/streams/grayscale-png/tortoise.png')
    .then(function(response) {
       return response.blob();
    })
    .then(function(myBlob) {
       let objectURL = URL.createObjectURL(myBlob);
       myImage.src = objectURL;
    });
}           

前面的两个示例中,我们通过 fetch 方法分别实现 JSON 数据的读取和图片的资源的获取功能。fetch 方法是 Fetch API 的核心方法,同时定义在 window 和 WorkerGlobalScope 环境中,因此我们可以在 Service Worker 环境中使用它。

Fetch 标准 中该方法的声明如下:

partial interface WindowOrWorkerGlobalScope {
  [NewObject] Promise fetch(RequestInfo input, optional RequestInit init);
};

通过观察上面的方法签名,我们可以知道 fetch 方法支持两个参数,调用后返回一个 Promise 对象。第二个参数是一个参数对象,用来初始化 Request。该参数对象有几个重要的属性:

了解详细的信息,请阅读 https://developer.mozilla.org/zh-CN/docs/Web/API/GlobalFetch/fetch

在 PWA 应用中,fetch API 的用武之地在于资源(比如图片、脚本文件或样式文件等)的获取。为了能够保证用户的离线体验,我们可以在获取资源时,对资源进行缓存。

具体示例如下:

self.addEventListener('fetch', (event) => {
  event.respondWith(
    caches.match(event.request).then((response) => {
      // 若缓存不存在,则使用fetch API从网上获取,然后利用Cache API缓存资源。
      return response || fetch(event.request).then((response) => {
          return caches.open('v1').then((cache) => {
            cache.put(event.request, response.clone());
            return response;
          });
     }); 
   })
  );
});

对于 Cache API,我们下一篇会介绍。这里需要注意的是,在使用 cache.put() 保存资源时,我们调用 response 对象的 clone() 方法,而不是直接保存 response 对象。为什么需要克隆响应对象呢?这是因为 Request 和 Response 的 body (响应体)只能被读取一次!它们有一个属性叫 bodyUsed,读取一次之后设置为 true,就不能再读取了。

本文只是简单介绍了 fetch API,其实 fetch API 还有很多东西需要进一步了解,如设置请求头、处理 Text/HTML 资源、表单提交、Cookies 与 CORS 处理等。这里就不再展开了,有兴趣的小伙伴,请自行查阅相关资料。

TAGS: [ #cn-programming ] [ #pwa ] [ #cn ]

Replies

NO REPLIES FOUND.

[ BACK TO TRENDING ] [ BACK TO MENU ]
CMD>