Chrome 開發工具之 Application

  • 2019 年 10 月 3 日
  • 筆記
Chrome 開發者工具有 Application 這麼一個面板,主要作用是檢查 web 應用加載的所有資源,包括 Manifest、Service Workers、Local Storage、Session Storage、IndexedDB、Web SQL(該標準早已廢棄,被 IndexedDB 干趴下)、Cookies、Cache Storage、Application Cache(已被 Service Workers 干趴下)、BackGround Services(頭一回見,和 sw 相關)、Frames 等。

下面將探索一番如何使用 Application 來查看及操作這些資源。

Manifest

在前端,有多個 manifest 相關的知識,比如 html5 manifest(已廢棄)、PWA(Progressive Web App)的 manifest、webpack 的 manifest(模塊資源清單)。
 
Applicaation 面板中的是指 PWA 所需的 manifest.json 文件,其作用是用來告訴瀏覽器如何在用戶的桌面上”安裝”這個 app,及安裝後該展示的信息。
 
在 Application 面板中,主要是展示其信息,不具有操作性質,展示圖如下(下面只是個簡單的不嚴格的本地 PWA 示例):

manifest.json
{    "name": "testApp",    "short_name": "tApp",    "display": "fullscreen",    "background_color": "#000",    "start_url": "/",    "description": "A test web app for manifest",    "icons": [      {        "src": "https://developers.google.com/web/images/web-fundamentals-icon192x192.png",        "type": "image/png",        "sizes": "192x192"      }    ]  }

 
效果:
 
從圖中可以看到,該面板顯示了 manifest.json 里的相關信息,並且給出指向到這個文件的鏈接。
 
想要了解更多 manifest 內容可參考:

注意:該功能兼容性目前僅 Chrome73+ 和 Edge 76 支持。

Service Workers & Cache Storage & Background Services

這三個選項放在一起寫了… 因為沒寫出抽離出 sw 後的 Cache Storage 和 Background Services。儘管 Cache Storage 在 mdn 里的描述據說是可以單獨使用的…
 
Service Workers 是獨立於當前頁面的一段運行在瀏覽器後台進程里的腳本,由於運行在 worker 上下文,因此它不能訪問 DOM,不過可以做一些簡單的輔助性邏輯處理和離線緩存等。兼容性的話…除了 IE 都還行。

Cache Storage 可以認為是 sw 緩存的資源列表(至少現在暫時是這麼認為的…因為當前沒能寫出也沒找到合適的其他場景的例子)。兼容的話,同 Service Workers.

Background Services Background FetchBackground Sync,前者用於生成在後台掛起的 fetch 資源任務,後者是生成在後台掛起執行的同步任務。兼容性的話…除了 Chrome 49+ 和 Edge 76+ 和 Opera 36+,其他都不行。

in test.html:
if ('serviceWorker' in navigator) {    const sw = navigator.serviceWorker      .register('/testhtml/sw.js', { scope: '/testhtml/' })      .then(function(reg) {        if (reg.installing) {          console.log('Service worker installing')        } else if (reg.waiting) {          console.log('Service worker installed')        } else if (reg.active) {          console.log('Service worker active')        }        reg.update()      })      .catch(function(error) {        console.log('Registration failed with ' + error)      })      navigator.serviceWorker.ready.then(sw => {      return sw.sync.register('hello-sync')    })      navigator.serviceWorker.ready.then(async sw => {      const bgFetch = await sw.backgroundFetch.fetch('custom-fetch', ['1.jpg'], {        title: 'download 1.jpg',        icons: [          {            sizes: '300x300',            src: '2.jpg',            type: 'image/jpg'          }        ]      })    })  }

 
sw.js:
self.addEventListener('install', event => {    event.waitUntil(      caches.open('v1').then(cache => {        return cache.addAll([          '/testhtml/test.html',          '/testhtml/test.css',          '/testhtml/test.js',          '/testhtml/2.jpg'        ])      })    )  })    self.addEventListener('sync', event => {    if (event.tag == 'hello-sync') {      console.log('receive hello-sync')    }  })    self.addEventListener('fetch', event => {    event.respondWith(      caches.match(event.request).then(response => {        if (response !== undefined) {          return response        } else {          return fetch(event.request)            .then(response => {              let responseClone = response.clone()              caches.open('cache_1').then(cache => {                cache.put(event.request, responseClone)              })              return response            })            .catch(() => {})        }      })    )  })

 
效果如下
 
Service Workers:

圖中 Sync 功能可以觸發 Background Sync 事件,並記錄到對應面板列表中。

Cache Storage:

列表的內容是只讀的。圖中的一些簡單篩選刷新操作就不多做贅述了…

Background Fetch:
 
列表的內容是只讀的。圖中可以看到,一次 fetch 的各個階段狀態轉變都會被記錄:Background Fetch registered => Background Fetch started => Request processing started => Request processing completed => Background Fetch completed.

Background Sync:
 
列表的內容是只讀的。圖中可以看到,一次 sync 的各個階段狀態轉變都也都會被記錄:Registered sync => Dispatched sync event => Sync completed.

參考文檔:

Clear storage

該面板主要用於展示當前瀏覽器存儲信息的一個總覽清除各種緩存(可自行勾選所需清理的內容),面板如下:
 
圖中可以看到,可清理有:
  • 卸載 services workers
  • Local storage 和 Session storage
  • IndexedDB 數據
  • Web SQL 數據
  • Cookies
  • Cache storage
  • 圖中底下還有 Application Cache 的選項未能截全…

Local Storage & Seesion Storage

他們兩都屬於 Web Storage,且兼容比較好。兩者區別是:localStorage 的生命周期是需要人為干涉的,sessionStorage 的生命周期是一次會話窗口。
 
Local Storage 面板和 Seesion Storage 面板顯示的是瀏覽器的 localStorage/sessionStorage 鍵值對(KVP)數據(該數據大小在 2~5MB 之間,各瀏覽器,各平台不同),在這個面板中。你可以執行查看值、雙擊空行新增 KVP、雙擊 KVP 對齊進行修改、刪除 KVP 等操作。

代碼:
localStorage.setItem('astring', 'This is an apple')  localStorage.setItem('aobject', { say: 'hello' })  localStorage.setItem('aboolean', false)

效果如下(Session Storage 面板情況是一樣):

吶,看上圖知道,數據在存取的時候都得是`string`類型。

更多信息參考:

IndexedDB

IndexDB 是瀏覽器端提供的本地存儲鍵值對的數據庫,建立在事務數據庫模型上(所做的操作都發生在創建的事務對象上下文),其 api 大多都是異步的。

在 IndexedDB 面板,可以查看、刪除 IndexedDB 內的數據(注意,不可以修改)。

代碼:
const IDBOpenDBRequest = indexedDB.open('testDB', 1)  IDBOpenDBRequest.onsuccess = e => {    const db = IDBOpenDBRequest.result    const transaction = db.transaction(['User', 'Book'], 'readwrite')    const objStore = transaction.objectStore('User')    const objBookStore = transaction.objectStore('Book')    // User 表加2條數據    objStore.put({      name: 'xiaoming',      age: 18,      sex: 1    })    objStore.put({      name: 'xiaohong',      age: 18,      sex: 2    })    // Book 表加一條數據    objBookStore.put({      bookName: '< hello world >',      price: 29,      status: 1    })  }  IDBOpenDBRequest.onupgradeneeded = e => {    const db = IDBOpenDBRequest.result    const store = db.createObjectStore('User', {      keyPath: 'name'    })    store.createIndex('name', 'name')    store.createIndex('age', 'age')    store.createIndex('sex', 'sex')    const bookStore = db.createObjectStore('Book', {      keyPath: 'id',      autoIncrement: true    })    bookStore.createIndex('bookName', 'bookName')    bookStore.createIndex('price', 'price')    bookStore.createIndex('status', 'status')  }

大致效果如下:
 
意外的是這玩意(這個數據庫很 js…)竟然干翻了原先的 [Web SQL](https://www.w3.org/TR/webdatabase/)(這個數據庫比較 sql…),更意外的這玩意的兼容性還算不錯…

更多 IndexedDB 信息參考:
 
Cookies

Cookies 面板查看、新增(僅限)、修改、刪除 http cookies。

比如在 nginx 上設置 cookies:
add_header Set-Cookie "say=hello;Domain=local.tuya-inc.cn;Path=/;Max-Age=10000";

效果如下:

當前的 cookies 值是可以通過 js 代碼獲取和修改的,也可以直接修改。如果不希望 js 可以操控該條 cookies,則需要在 Set-Cookies 時加上`httpOnly`字段。

Frames

該面板顯示了該網站所有內容資源。效果如圖:

 

 

注意下,iframe 的內容不能預覽,如果頁面帶`x-frame-options=SAMEORIGIN`,則其他域名網站就嵌入不了額。

最後

工欲善其事,必先利其器… 作為一個開發者,對 Chrome 和 FireFox 的開發者工具都需要更多更詳細的了解,才能在開發和調試工作中更順利。