1. 程式人生 > >Chrome 開發工具之 Application

Chrome 開發工具之 Application

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 內容可參考: web-app-manifest app-install-banners
注意:該功能相容性目前僅 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 Fetch 和 Background 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.
參考文件: Service Workers - mdn Service Workers Cache Storage Background Fetch Background Sync
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`型別。
更多資訊參考: localStorage - mdn the-localstorage-attribute
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 資訊參考: 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 的開發者工具都需要更多更詳細的瞭解,才能在開發和除錯工作中更順利。

&n