|
@@ -0,0 +1,197 @@
|
|
|
+// 异常资源数组
|
|
|
+const failedResources = [];
|
|
|
+
|
|
|
+// 异常域名数组
|
|
|
+const domains = [];
|
|
|
+
|
|
|
+// 备用域名映射
|
|
|
+const BackCDNs = {
|
|
|
+ 'cdn-jybx-webtest.jydev.jianyu360.com': 'jybx2-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',
|
|
|
+ 'cdn-ali2.jianyu360.cn': 'cdn-ali2.jianyu360.com',
|
|
|
+ 'cdn-ali3.jianyu360.cn': 'cdn-ali3.jianyu360.com',
|
|
|
+ 'cdn-ali4.jianyu360.cn': 'cdn-ali4.jianyu360.com',
|
|
|
+ 'cdn-common.jianyu360.cn': 'cdn-common.jianyu360.com',
|
|
|
+}
|
|
|
+
|
|
|
+// 处理异常资源
|
|
|
+const handleResourceError = (url) => {
|
|
|
+ failedResources.push(url);
|
|
|
+
|
|
|
+ // 提取域名
|
|
|
+ const domain = new URL(url).hostname;
|
|
|
+ if(!domains.includes(domain)) {
|
|
|
+ domains.push(domain);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 监听错误事件
|
|
|
+window.addEventListener('error', (e) => {
|
|
|
+ // 脚本错误
|
|
|
+ if(e.target.src && e.target.tagName === 'SCRIPT') {
|
|
|
+ handleResourceError(e.target.src);
|
|
|
+ }
|
|
|
+
|
|
|
+ // CSS错误
|
|
|
+ if(e.target.href && e.target.tagName === 'LINK') {
|
|
|
+ handleResourceError(e.target.href);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 图片错误
|
|
|
+ if(e.target.src && e.target.tagName === 'IMG') {
|
|
|
+ handleResourceError(e.target.src);
|
|
|
+ }
|
|
|
+
|
|
|
+}, true);
|
|
|
+
|
|
|
+// 插入弹窗 Node
|
|
|
+let initCDNDialog = false
|
|
|
+function addCDNDialogNode () {
|
|
|
+ if (initCDNDialog) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ initCDNDialog = true
|
|
|
+ const cdnStyle = document.createElement('style')
|
|
|
+ cdnStyle.innerHTML = `
|
|
|
+ <style>
|
|
|
+
|
|
|
+ .cdn-tip--dialog.show.action-tip .tip-button--submit {
|
|
|
+ display: none;
|
|
|
+ }
|
|
|
+ .cdn-tip--dialog.show,
|
|
|
+ .cdn-tip--dialog.show button{
|
|
|
+ display: inline-block;
|
|
|
+ }
|
|
|
+ .cdn-tip--dialog {
|
|
|
+ position: fixed;
|
|
|
+ top: 20%;
|
|
|
+ left: 50%;
|
|
|
+ transform: translateX(-50%);
|
|
|
+ display: none;
|
|
|
+ box-shadow: 0 0 2px 1px #e0e0e0;
|
|
|
+ border-radius: 8px;
|
|
|
+ background: #FFF;
|
|
|
+ padding: 32px;
|
|
|
+ color: #686868;
|
|
|
+ text-align: center;
|
|
|
+ font-size: 14px;
|
|
|
+ font-style: normal;
|
|
|
+ font-weight: 400;
|
|
|
+ line-height: 22px;
|
|
|
+ }
|
|
|
+ .cdn-tip--dialog button.tip-button--submit {
|
|
|
+ background: #2ABED1;
|
|
|
+ color: #FFF;
|
|
|
+ }
|
|
|
+ .cdn-tip--dialog button {
|
|
|
+ display: none;
|
|
|
+ border-radius: 6px;
|
|
|
+ width: 132px;
|
|
|
+ height: 36px;
|
|
|
+ flex-shrink: 0;
|
|
|
+ line-height: 36px;
|
|
|
+ border: none;
|
|
|
+ margin: 6px;
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
+ </style>
|
|
|
+`
|
|
|
+ document.head.appendChild(cdnStyle)
|
|
|
+
|
|
|
+ const cdnNode = document.createElement('div')
|
|
|
+ cdnNode.innerHTML = `
|
|
|
+ <div class="cdn-tip--dialog" id="cdn-tip">
|
|
|
+ <p>
|
|
|
+ 检测到当前页面故障,是否尝试进行修复?
|
|
|
+ <br>
|
|
|
+ 您也可自行联系您的网络管理员获得支持
|
|
|
+ </p>
|
|
|
+ <div>
|
|
|
+ <button class="tip-button--submit" onclick="location.reload()">尝试修复</button>
|
|
|
+ <button class="tip-button--cancel" onclick="location.href = 'https://www.jianyu360.cn/assets-inspect.html'">联系网络管理员</button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ `
|
|
|
+ document.body.appendChild(cdnNode)
|
|
|
+}
|
|
|
+
|
|
|
+window.addEventListener('load', () => {
|
|
|
+ // 页面完全加载完毕
|
|
|
+ console.log('load Failed resources:', failedResources)
|
|
|
+ console.log('load Extracted domains:', domains)
|
|
|
+
|
|
|
+ // 存储
|
|
|
+ caches.open('CDN_INSPECT_2SW').then(cache => {
|
|
|
+ cache.put('data', new Response(JSON.stringify({
|
|
|
+ FailedCDNs: domains,
|
|
|
+ BackCDNs: BackCDNs
|
|
|
+ })))
|
|
|
+ })
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ 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 () {
|
|
|
+ // 注册 Service Worker
|
|
|
+ if ('serviceWorker' in navigator) {
|
|
|
+ const cdnTipNode = document.querySelector('#cdn-tip')
|
|
|
+ navigator.serviceWorker.register('/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()
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+
|