Răsfoiți Sursa

feat: 优化代码

zhangyuhan 2 ani în urmă
părinte
comite
3816c9a71e

+ 92 - 71
src/web/staticres/brand/js/detection.js

@@ -1,3 +1,66 @@
+/**
+ * 初始化sw脚本
+ */
+function initServiceWorkerScript (callback) {
+  function removeServiceWorker () {
+    if ("serviceWorker" in navigator) {
+      navigator.serviceWorker
+        .register("/sw.js")
+        .then(function (registration) {
+          // registration worked
+          console.log("Registration succeeded.");
+          registration.unregister().then(function (boolean) {
+            // if boolean = true, unregister is successful
+            console.log('b', boolean)
+          });
+        })
+        .catch(function (error) {
+          // registration failed
+          console.log("Registration failed with " + error);
+        });
+    }
+  }
+
+  function addServiceWorker (callback) {
+    // 注册 Service Worker
+    if ('serviceWorker' in navigator) {
+      navigator.serviceWorker.register('/sw.js')
+        .then((res) => {
+          console.log('SW Init')
+          try {
+            res.active.postMessage({
+              type: 'update-sw-cache'
+            })
+          } catch (err) {
+            console.log('SW Not Active', err)
+          }
+          typeof callback === "function" && callback(true)
+        })
+        .catch(err => {
+          console.log('SW failed', err)
+          typeof callback === "function" && callback(false)
+        });
+    } else {
+      typeof callback === "function" && callback(true)
+    }
+  }
+
+  navigator.serviceWorker.addEventListener('controllerchange', () => {
+    // 当service worker管控页面时触发
+    alert("检测到资源修复脚本更新,请刷新页面");
+  })
+
+  const runSw = localStorage.getItem('run-cdn') === 'true'
+  console.log('是否启用拦截', runSw)
+
+  if (runSw) {
+    addServiceWorker(callback)
+  } else {
+    removeServiceWorker()
+  }
+}
+initServiceWorkerScript()
+
 // 异常资源数组
 const failedResources = [];
 
@@ -6,7 +69,7 @@ const domains = [];
 
 // 备用域名映射
 const BackCDNs = {
-  'jybx3-webtest.jydev.jianyu360.com': 'jybx-webtest.jydev.jianyu360.com',
+  'cdn-jybx-webtest.jydev.jianyu360.com': 'jybx-webtest.jydev.jianyu360.com',
   'cdn-ali222.jianyu360.com': 'cdn-ali2.jianyu360.com',
   'cdn-ali222.jianyu360.cn': 'cdn-ali2.jianyu360.com',
   'cdn-ali.jianyu360.cn': 'cdn-ali.jianyu360.com',
@@ -48,7 +111,7 @@ window.addEventListener('error', (e) => {
 
 // 插入弹窗 Node
 let initCDNDialog = false
-function addCDNDialogNode () {
+function addCDNDialogNode (callback) {
   if (initCDNDialog) {
     return
   }
@@ -100,16 +163,18 @@ function addCDNDialogNode () {
 `
   document.head.appendChild(cdnStyle)
 
+  window._CDN_ON_CALLBACK_ = callback
+
   const cdnNode = document.createElement('div')
   cdnNode.innerHTML = `
-  <div class="cdn-tip--dialog" id="cdn-tip">
+  <div class="cdn-tip--dialog show" id="cdn-tip">
     <p>
       检测到当前页面故障,是否尝试进行修复?
       <br>
       您也可自行联系您的网络管理员获得支持
     </p>
     <div>
-      <button class="tip-button--submit" onclick="location.reload()">尝试修复</button>
+      <button class="tip-button--submit" onclick="window._CDN_ON_CALLBACK_(true)">尝试修复</button>
       <button class="tip-button--cancel" onclick="location.href = 'https://www.jianyu360.cn/assets-inspect.html'">联系网络管理员</button>
     </div>
   </div>
@@ -122,76 +187,32 @@ window.addEventListener('load', () => {
   console.log('load Failed resources:', failedResources)
   console.log('load Extracted domains:', domains)
 
-  // 存储
-  caches.open('CDN_INSPECT_2SW').then(cache => {
-    cache.put('/CDN-DATA', new Response(JSON.stringify({
-      FailedCDNs: domains,
-      BackCDNs: BackCDNs
-    })))
-  })
-
-
-
-  function removeServiceWorker () {
-    if ("serviceWorker" in navigator) {
-      navigator.serviceWorker
-        .register("brand/js/sw.js")
-        .then(function (registration) {
-          // registration worked
-          console.log("Registration succeeded.");
-          registration.unregister().then(function (boolean) {
-            // if boolean = true, unregister is successful
-            console.log('b', boolean)
-          });
-        })
-        .catch(function (error) {
-          // registration failed
-          console.log("Registration failed with " + error);
-        });
-    }
-  }
-
-  function addServiceWorker () {
-    // 注册 Service Worker
-    if ('serviceWorker' in navigator) {
-      const cdnTipNode = document.querySelector('#cdn-tip')
-      navigator.serviceWorker.register('/brand/js/sw.js')
-        .then(() => {
-          // 通知用户
-          cdnTipNode.classList.add('show')
-        })
-        .catch(err => {
-          // 通知用户
-          cdnTipNode.classList.add('show')
-          cdnTipNode.classList.add('action-tip')
-
-          console.log('SW failed', err)
-        });
-
-      navigator.serviceWorker.addEventListener('controllerchange', () => {
-        // 当service worker管控页面时触发
-        alert("检测到SW更新,请刷新页面");
-      })
-    }
-  }
-
-  const stopSw = localStorage.getItem('stop-cdn') === 'true'
-
-  console.log('是否禁用拦截', stopSw)
-
-  if (stopSw) {
-    removeServiceWorker()
-  }
-
-
   const hasBackCDN = Object.keys(BackCDNs).some(v => domains.includes(v))
-
   console.log('异常域名是否包含备用', hasBackCDN)
 
-  if (!stopSw && domains.length && hasBackCDN) {
-    addCDNDialogNode()
-    addServiceWorker()
+  const canNext = domains.length && hasBackCDN
+  console.log('是否存在可修复的异常域名', canNext)
+
+  if (canNext) {
+    // 存储
+    caches.open('CDN_INSPECT_2SW').then(cache => {
+      cache.put('/CDN-DATA', new Response(JSON.stringify({
+        FailedCDNs: domains,
+        BackCDNs: BackCDNs
+      })))
+    })
+
+    addCDNDialogNode(function () {
+      localStorage.setItem('run-cdn', true)
+      initServiceWorkerScript(function (state) {
+        if (state) {
+          location.reload()
+        } else {
+          alert('修复脚本加载失败')
+        }
+      })
+    })
   }
-});
+})
 
 

+ 45 - 37
src/web/staticres/brand/js/sw.js

@@ -1,9 +1,15 @@
 // 获取历史数据或缓存
 let data = {}
 
-self.addEventListener('install', async function (event) {
-  console.log('install v21');
+console.log('[sw] run: ', Date.now())
+async function getData () {
   data = await getCacheShareData()
+  console.log('[sw] data: ', data)
+}
+getData()
+
+self.addEventListener('install', function (event) {
+  console.log('install v0802-5');
   self.skipWaiting();
 });
 
@@ -12,8 +18,6 @@ self.addEventListener('activate', function (event) {
 });
 
 
-
-
 /**
  * 根据 Key 读取缓存
  * @param key
@@ -22,7 +26,7 @@ self.addEventListener('activate', function (event) {
 async function getCacheShareData (key = 'CDN_INSPECT_2SW') {
   return await caches.open(key).then(async cache => {
     const res = await cache.match('/CDN-DATA')
-    const data = await res.json();
+    const data = await res?.json() || {};
 
     console.log(`get ${key} data`, data)
 
@@ -46,36 +50,40 @@ function setCacheShareData (data, key = 'CDN_INSPECT_2PAGE') {
 // 已拦截的CDN
 const ProxyCDNS = []
 
-
 self.addEventListener('fetch',(event) => {
-
-
-  // TODO 清除缓存逻辑
-
-
-  const {
-    FailedCDNs = [],
-    BackCDNs = {}
-  } = data || {};
-
-  console.warn('[Cache]: ', data)
-
-
-  const url = new URL(event.request.url);
-  const domain = url.hostname;
-
-  console.warn(`[Fetch 拦截]: ${domain} -- ${url}`)
-
-
-
-  if(FailedCDNs.includes(domain)) {
-    url.hostname = BackCDNs[domain] || '';
-    console.warn(`[>>>>>>>>>>>>>>>>>>>>> CDN 异常转发]: ${domain} -- ${url}`)
-    if (!ProxyCDNS.includes(domain)) {
-      ProxyCDNS.push(domain)
-      setCacheShareData(ProxyCDNS)
-    }
-    event.respondWith(fetch(url));
-  }
-
-});
+  console.log('[sw] fetch: ', event)
+})
+
+// self.addEventListener('fetch',(event) => {
+//
+//   getData()
+//
+//   // TODO 清除缓存逻辑
+//
+//
+//   const {
+//     FailedCDNs = [],
+//     BackCDNs = {}
+//   } = data || {};
+//
+//   console.warn('[Cache]: ', data)
+//
+//
+//   const url = new URL(event.request.url);
+//   const domain = url.hostname;
+//
+//   console.warn(`[Fetch 拦截]: ${domain} -- ${url}`)
+//
+//
+//
+//   if(FailedCDNs.includes(domain)) {
+//     url.hostname = BackCDNs[domain] || '';
+//     console.warn(`[>>>>>>>>>>>>>>>>>>>>> CDN 异常转发]: ${domain} -- ${url}`)
+//     if (!ProxyCDNS.includes(domain)) {
+//       ProxyCDNS.push(domain)
+//       setCacheShareData(ProxyCDNS)
+//     }
+//     event.respondWith(fetch(url));
+//   }
+//
+// });

+ 115 - 0
src/web/staticres/sw.js

@@ -0,0 +1,115 @@
+/**
+ * log
+ * @param params
+ */
+function log (...params) {
+  console.warn('[sw log]:', ...params)
+}
+
+/**
+ * 根据 Key 读取缓存
+ * @param key
+ * @return {Promise<any>}
+ */
+async function getCacheShareData (key = 'CDN_INSPECT_2SW') {
+  return await caches.open(key).then(async cache => {
+    const res = await cache.match('/CDN-DATA')
+    const data = await res?.json() || {}
+    log(`get ${key} data`, data)
+    return data
+  });
+}
+
+/**
+ * 设置缓存
+ * @param data
+ * @param key
+ */
+function setCacheShareData (data, key = 'CDN_INSPECT_2PAGE') {
+  // 写入缓存
+  caches.open(key).then(cache => {
+    cache.put('/CDN-DATA', new Response(JSON.stringify(data)))
+  })
+}
+
+/**
+ * 防抖
+ * @param func
+ * @param delay
+ * @return {(function(...[*]): void)|*}
+ */
+function debounce(func, delay) {
+  let timerId;
+
+  return function(...args) {
+    if (timerId) {
+      clearTimeout(timerId);
+    }
+
+    timerId = setTimeout(() => {
+      func.apply(this, args);
+      timerId = null;
+    }, delay);
+  }
+}
+
+// 全局缓存数据
+let data = {}
+// 已拦截的CDN
+const ProxyCDNS = []
+const version = 'v8.2.1'
+
+/**
+ * 更新缓存 data 值
+ * @type {(function(...[*]): void)|*}
+ */
+const getData = debounce(async function () {
+  data = await getCacheShareData()
+  log('get cache data: ', data)
+}, 1000)
+
+/**
+ * 生命周期
+ */
+self.addEventListener('install', () => {
+  log(`install script ${version}`)
+  self.skipWaiting()
+});
+
+self.addEventListener('activate',() => {
+  log('activate')
+  getData()
+})
+
+self.addEventListener('message', event => {
+  const message = event.data
+  if (message.type === 'update-sw-cache') {
+    log('update cache')
+    getData()
+  }
+})
+
+
+self.addEventListener('fetch',(event) => {
+  getData()
+  // TODO 清除缓存逻辑
+  const {
+    FailedCDNs = [],
+    BackCDNs = {}
+  } = data || {}
+  log('(Cache)', data)
+
+  const url = new URL(event.request.url)
+  const domain = url.hostname;
+  log(`(Fetch) ${domain} -- ${url}`)
+
+  if(FailedCDNs.includes(domain) && BackCDNs[domain]) {
+    url.hostname = BackCDNs[domain];
+    log(`(Proxy) ${domain} -- ${url}`)
+    if (!ProxyCDNS.includes(domain)) {
+      ProxyCDNS.push(domain)
+      setCacheShareData(ProxyCDNS)
+    }
+    event.respondWith(fetch(url))
+  }
+})

+ 5 - 5
src/web/templates/frontRouter/pc/brand/free/dev.html

@@ -39,8 +39,8 @@
 
 <h3>当前启用状态:<span style="color: #0A9AEA"></span></h3>
 
-<button onclick="changeStorageStatus(false)">启用修复</button>
-<button style="background: #ff0000c2" onclick="changeStorageStatus(true)">禁用修复</button>
+<button onclick="changeStorageStatus(true)">启用修复</button>
+<button style="background: #ff0000c2" onclick="changeStorageStatus(false)">禁用修复</button>
 
 
 <h2>已启用拦截映射的资源域名:</h2>
@@ -58,8 +58,8 @@
 <button onclick="location.reload()">刷新页面</button>
 
 <script>
-  // 是否禁用修复的缓存 key
-  const key = 'stop-cdn'
+  // 是否修复的缓存 key
+  const key = 'run-cdn'
 
   /**
    * 改变是否禁用修复缓存状态
@@ -75,7 +75,7 @@
    */
   function updateStorageStatus() {
     const stopState = localStorage.getItem(key) === 'true'
-    document.querySelector('h3 span').innerText = stopState ? '启用' : '启用'
+    document.querySelector('h3 span').innerText = stopState ? '启用' : '启用'
   }
 
   updateStorageStatus()