您好,登錄后才能下訂單哦!
本篇內(nèi)容介紹了“如何進(jìn)行數(shù)據(jù)采集和數(shù)據(jù)上報(bào)”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!
數(shù)據(jù)采集
性能數(shù)據(jù)采集
性能數(shù)據(jù)采集需要使用 window.performance API
https://developer.mozilla.org/zh-CN/docs/Web/API/Performance
Performance 接口可以獲取到當(dāng)前頁(yè)面中與性能相關(guān)的信息,它是 High Resolution Time API 的一部分,同時(shí)也融合了 Performance Timeline API、Navigation Timing API、 User Timing API 和 Resource Timing API。
從 MDN 的文檔可以看出,window.performance.timing 包含了頁(yè)面加載各個(gè)階段的起始及結(jié)束時(shí)間。
這些屬性需要結(jié)合下圖一起看,更好理解:
在這里插入圖片描述
為了方便大家理解 timing 各個(gè)屬性的意義,我在知乎找到一位網(wǎng)友對(duì)于 timing 寫(xiě)的簡(jiǎn)介,在此轉(zhuǎn)載一下。
timing: { // 同一個(gè)瀏覽器上一個(gè)頁(yè)面卸載(unload)結(jié)束時(shí)的時(shí)間戳。如果沒(méi)有上一個(gè)頁(yè)面,這個(gè)值會(huì)和fetchStart相同。 navigationStart: 1543806782096, // 上一個(gè)頁(yè)面unload事件拋出時(shí)的時(shí)間戳。如果沒(méi)有上一個(gè)頁(yè)面,這個(gè)值會(huì)返回0。 unloadEventStart: 1543806782523, // 和 unloadEventStart 相對(duì)應(yīng),unload事件處理完成時(shí)的時(shí)間戳。如果沒(méi)有上一個(gè)頁(yè)面,這個(gè)值會(huì)返回0。 unloadEventEnd: 1543806782523, // 第一個(gè)HTTP重定向開(kāi)始時(shí)的時(shí)間戳。如果沒(méi)有重定向,或者重定向中的一個(gè)不同源,這個(gè)值會(huì)返回0。 redirectStart: 0, // 最后一個(gè)HTTP重定向完成時(shí)(也就是說(shuō)是HTTP響應(yīng)的最后一個(gè)比特直接被收到的時(shí)間)的時(shí)間戳。 // 如果沒(méi)有重定向,或者重定向中的一個(gè)不同源,這個(gè)值會(huì)返回0. redirectEnd: 0, // 瀏覽器準(zhǔn)備好使用HTTP請(qǐng)求來(lái)獲取(fetch)文檔的時(shí)間戳。這個(gè)時(shí)間點(diǎn)會(huì)在檢查任何應(yīng)用緩存之前。 fetchStart: 1543806782096, // DNS 域名查詢開(kāi)始的UNIX時(shí)間戳。 //如果使用了持續(xù)連接(persistent connection),或者這個(gè)信息存儲(chǔ)到了緩存或者本地資源上,這個(gè)值將和fetchStart一致。 domainLookupStart: 1543806782096, // DNS 域名查詢完成的時(shí)間. //如果使用了本地緩存(即無(wú) DNS 查詢)或持久連接,則與 fetchStart 值相等 domainLookupEnd: 1543806782096, // HTTP(TCP) 域名查詢結(jié)束的時(shí)間戳。 //如果使用了持續(xù)連接(persistent connection),或者這個(gè)信息存儲(chǔ)到了緩存或者本地資源上,這個(gè)值將和 fetchStart一致。 connectStart: 1543806782099, // HTTP(TCP) 返回瀏覽器與服務(wù)器之間的連接建立時(shí)的時(shí)間戳。 // 如果建立的是持久連接,則返回值等同于fetchStart屬性的值。連接建立指的是所有握手和認(rèn)證過(guò)程全部結(jié)束。 connectEnd: 1543806782227, // HTTPS 返回瀏覽器與服務(wù)器開(kāi)始安全鏈接的握手時(shí)的時(shí)間戳。如果當(dāng)前網(wǎng)頁(yè)不要求安全連接,則返回0。 secureConnectionStart: 1543806782162, // 返回瀏覽器向服務(wù)器發(fā)出HTTP請(qǐng)求時(shí)(或開(kāi)始讀取本地緩存時(shí))的時(shí)間戳。 requestStart: 1543806782241, // 返回瀏覽器從服務(wù)器收到(或從本地緩存讀?。┑谝粋€(gè)字節(jié)時(shí)的時(shí)間戳。 //如果傳輸層在開(kāi)始請(qǐng)求之后失敗并且連接被重開(kāi),該屬性將會(huì)被數(shù)制成新的請(qǐng)求的相對(duì)應(yīng)的發(fā)起時(shí)間。 responseStart: 1543806782516, // 返回瀏覽器從服務(wù)器收到(或從本地緩存讀取,或從本地資源讀?。┳詈笠粋€(gè)字節(jié)時(shí) //(如果在此之前HTTP連接已經(jīng)關(guān)閉,則返回關(guān)閉時(shí))的時(shí)間戳。 responseEnd: 1543806782537, // 當(dāng)前網(wǎng)頁(yè)DOM結(jié)構(gòu)開(kāi)始解析時(shí)(即Document.readyState屬性變?yōu)椤發(fā)oading”、相應(yīng)的 readystatechange事件觸發(fā)時(shí))的時(shí)間戳。 domLoading: 1543806782573, // 當(dāng)前網(wǎng)頁(yè)DOM結(jié)構(gòu)結(jié)束解析、開(kāi)始加載內(nèi)嵌資源時(shí)(即Document.readyState屬性變?yōu)椤癷nteractive”、相應(yīng)的readystatechange事件觸發(fā)時(shí))的時(shí)間戳。 domInteractive: 1543806783203, // 當(dāng)解析器發(fā)送DOMContentLoaded 事件,即所有需要被執(zhí)行的腳本已經(jīng)被解析時(shí)的時(shí)間戳。 domContentLoadedEventStart: 1543806783203, // 當(dāng)所有需要立即執(zhí)行的腳本已經(jīng)被執(zhí)行(不論執(zhí)行順序)時(shí)的時(shí)間戳。 domContentLoadedEventEnd: 1543806783216, // 當(dāng)前文檔解析完成,即Document.readyState 變?yōu)?nbsp;'complete'且相對(duì)應(yīng)的readystatechange 被觸發(fā)時(shí)的時(shí)間戳 domComplete: 1543806783796, // load事件被發(fā)送時(shí)的時(shí)間戳。如果這個(gè)事件還未被發(fā)送,它的值將會(huì)是0。 loadEventStart: 1543806783796, // 當(dāng)load事件結(jié)束,即加載事件完成時(shí)的時(shí)間戳。如果這個(gè)事件還未被發(fā)送,或者尚未完成,它的值將會(huì)是0. loadEventEnd: 1543806783802 }
通過(guò)以上數(shù)據(jù),我們可以得到幾個(gè)有用的時(shí)間
// 重定向耗時(shí) redirect: timing.redirectEnd - timing.redirectStart, // DOM 渲染耗時(shí) dom: timing.domComplete - timing.domLoading, // 頁(yè)面加載耗時(shí) load: timing.loadEventEnd - timing.navigationStart, // 頁(yè)面卸載耗時(shí) unload: timing.unloadEventEnd - timing.unloadEventStart, // 請(qǐng)求耗時(shí) request: timing.responseEnd - timing.requestStart, // 獲取性能信息時(shí)當(dāng)前時(shí)間 time: new Date().getTime(),
還有一個(gè)比較重要的時(shí)間就是白屏?xí)r間,它指從輸入網(wǎng)址,到頁(yè)面開(kāi)始顯示內(nèi)容的時(shí)間。
將以下腳本放在 </head> 前面就能獲取白屏?xí)r間。
<script> whiteScreen = new Date() - performance.timing.navigationStart // 通過(guò) domLoading 和 navigationStart 也可以 whiteScreen = performance.timing.domLoading - performance.timing.navigationStart </script>
通過(guò)這幾個(gè)時(shí)間,就可以得知頁(yè)面首屏加載性能如何了。
另外,通過(guò) window.performance.getEntriesByType('resource') 這個(gè)方法,我們還可以獲取相關(guān)資源(js、css、img...)的加載時(shí)間,它會(huì)返回頁(yè)面當(dāng)前所加載的所有資源。
在這里插入圖片描述
它一般包括以下幾個(gè)類(lèi)型:
sciprt
link
img
css
fetch
other
xmlhttprequest
我們只需用到以下幾個(gè)信息:
// 資源的名稱(chēng) name: item.name, // 資源加載耗時(shí) duration: item.duration.toFixed(2), // 資源大小 size: item.transferSize, // 資源所用協(xié)議 protocol: item.nextHopProtocol,
現(xiàn)在,寫(xiě)幾行代碼來(lái)收集這些數(shù)據(jù)。
// 收集性能信息 const getPerformance = () => { if (!window.performance) return const timing = window.performance.timing const performance = { // 重定向耗時(shí) redirect: timing.redirectEnd - timing.redirectStart, // 白屏?xí)r間 whiteScreen: whiteScreen, // DOM 渲染耗時(shí) dom: timing.domComplete - timing.domLoading, // 頁(yè)面加載耗時(shí) load: timing.loadEventEnd - timing.navigationStart, // 頁(yè)面卸載耗時(shí) unload: timing.unloadEventEnd - timing.unloadEventStart, // 請(qǐng)求耗時(shí) request: timing.responseEnd - timing.requestStart, // 獲取性能信息時(shí)當(dāng)前時(shí)間 time: new Date().getTime(), } return performance } // 獲取資源信息 const getResources = () => { if (!window.performance) return const data = window.performance.getEntriesByType('resource') const resource = { xmlhttprequest: [], css: [], other: [], script: [], img: [], link: [], fetch: [], // 獲取資源信息時(shí)當(dāng)前時(shí)間 time: new Date().getTime(), } data.forEach(item => { const arry = resource[item.initiatorType] arry && arry.push({ // 資源的名稱(chēng) name: item.name, // 資源加載耗時(shí) duration: item.duration.toFixed(2), // 資源大小 size: item.transferSize, // 資源所用協(xié)議 protocol: item.nextHopProtocol, }) }) return resource }
小結(jié)
通過(guò)對(duì)性能及資源信息的解讀,我們可以判斷出頁(yè)面加載慢有以下幾個(gè)原因:
鴻蒙官方戰(zhàn)略合作共建——HarmonyOS技術(shù)社區(qū)
資源過(guò)多、過(guò)大
網(wǎng)速過(guò)慢
DOM 元素過(guò)多
除了用戶網(wǎng)速過(guò)慢,我們沒(méi)辦法之外,其他兩個(gè)原因都是有辦法解決的,性能優(yōu)化的文章和書(shū)籍網(wǎng)上已經(jīng)有很多了,有興趣可自行查找資料了解。
PS:其實(shí)頁(yè)面加載慢還有其他原因,例如沒(méi)有使用按需加載、沒(méi)有使用 CDN 等等。不過(guò)這里我們強(qiáng)調(diào)的僅通過(guò)對(duì)性能和資源信息的解讀來(lái)獲取原因。
錯(cuò)誤數(shù)據(jù)采集
目前所能捕捉的錯(cuò)誤有三種:
鴻蒙官方戰(zhàn)略合作共建——HarmonyOS技術(shù)社區(qū)
資源加載錯(cuò)誤,通過(guò) addEventListener('error', callback, true) 在捕獲階段捕捉資源加載失敗錯(cuò)誤。
js 執(zhí)行錯(cuò)誤,通過(guò) window.onerror 捕捉 js 錯(cuò)誤。
promise 錯(cuò)誤,通過(guò) addEventListener('unhandledrejection', callback)捕捉 promise 錯(cuò)誤,但是沒(méi)有發(fā)生錯(cuò)誤的行數(shù),列數(shù)等信息,只能手動(dòng)拋出相關(guān)錯(cuò)誤信息。
我們可以建一個(gè)錯(cuò)誤數(shù)組變量 errors 在錯(cuò)誤發(fā)生時(shí),將錯(cuò)誤的相關(guān)信息添加到數(shù)組,然后在某個(gè)階段統(tǒng)一上報(bào),具體如何操作請(qǐng)看下面的代碼:
// 捕獲資源加載失敗錯(cuò)誤 js css img... addEventListener('error', e => { const target = e.target if (target != window) { monitor.errors.push({ type: target.localName, url: target.src || target.href, msg: (target.src || target.href) + ' is load error', // 錯(cuò)誤發(fā)生的時(shí)間 time: new Date().getTime(), }) } }, true) // 監(jiān)聽(tīng) js 錯(cuò)誤 window.onerror = function(msg, url, row, col, error) { monitor.errors.push({ type: 'javascript', row: row, col: col, msg: error && error.stack? error.stack : msg, url: url, // 錯(cuò)誤發(fā)生的時(shí)間 time: new Date().getTime(), }) } // 監(jiān)聽(tīng) promise 錯(cuò)誤 缺點(diǎn)是獲取不到行數(shù)數(shù)據(jù) addEventListener('unhandledrejection', e => { monitor.errors.push({ type: 'promise', msg: (e.reason && e.reason.msg) || e.reason || '', // 錯(cuò)誤發(fā)生的時(shí)間 time: new Date().getTime(), }) })
小結(jié)
通過(guò)錯(cuò)誤收集,可以了解到網(wǎng)站發(fā)生錯(cuò)誤的類(lèi)型及數(shù)量,從而做出相應(yīng)的調(diào)整,以減少錯(cuò)誤發(fā)生。完整代碼和 DEMO 會(huì)在文章末尾放出,大家可以復(fù)制代碼(HTML文件)在本地測(cè)試一下。
數(shù)據(jù)上報(bào)
性能數(shù)據(jù)上報(bào)
性能數(shù)據(jù)可以在頁(yè)面加載完之后上報(bào),盡量不要對(duì)頁(yè)面性能造成影響。
window.onload = () => { // 在瀏覽器空閑時(shí)間獲取性能及資源信息 // https://developer.mozilla.org/zh-CN/docs/Web/API/Window/requestIdleCallback if (window.requestIdleCallback) { window.requestIdleCallback(() => { monitor.performance = getPerformance() monitor.resources = getResources() }) } else { setTimeout(() => { monitor.performance = getPerformance() monitor.resources = getResources() }, 0) } }
當(dāng)然,你也可以設(shè)一個(gè)定時(shí)器,循環(huán)上報(bào)。不過(guò)每次上報(bào)最好做一下對(duì)比去重再上報(bào),避免同樣的數(shù)據(jù)重復(fù)上報(bào)。
錯(cuò)誤數(shù)據(jù)上報(bào)
我在 DEMO 里提供的代碼,是用一個(gè) errors 數(shù)組收集所有的錯(cuò)誤,再在某一階段統(tǒng)一上報(bào)(延時(shí)上報(bào))。
其實(shí),也可以改成在錯(cuò)誤發(fā)生時(shí)上報(bào)(即時(shí)上報(bào))。這樣可以避免“收集完錯(cuò)誤,但延時(shí)上報(bào)還沒(méi)觸發(fā),用戶卻已經(jīng)關(guān)掉網(wǎng)頁(yè)導(dǎo)致錯(cuò)誤數(shù)據(jù)丟失”的問(wèn)題。
// 監(jiān)聽(tīng) js 錯(cuò)誤 window.onerror = function(msg, url, row, col, error) { const data = { type: 'javascript', row: row, col: col, msg: error && error.stack? error.stack : msg, url: url, // 錯(cuò)誤發(fā)生的時(shí)間 time: new Date().getTime(), } // 即時(shí)上報(bào) axios.post({ url: 'xxx', data, }) }
經(jīng)網(wǎng)友提醒,可以使用 navigator.sendBeacon() 來(lái)進(jìn)行上報(bào)。
window.addEventListener('unload', logData, false); function logData() { navigator.sendBeacon("/log", analyticsData); }
它的技術(shù)特點(diǎn)是:
使用 sendBeacon() 方法會(huì)使用戶代理(瀏覽器)在有機(jī)會(huì)時(shí)異步地向服務(wù)器發(fā)送數(shù)據(jù),同時(shí)不會(huì)延遲頁(yè)面的卸載或影響下一導(dǎo)航的載入性能。這就解決了提交分析數(shù)據(jù)時(shí)的所有的問(wèn)題:數(shù)據(jù)可靠,傳輸異步并且不會(huì)影響下一頁(yè)面的加載。
擴(kuò)展
SPA
window.performance API 是有缺點(diǎn)的,在 SPA 切換路由時(shí),window.performance.timing 的數(shù)據(jù)不會(huì)更新。所以我們需要另想辦法來(lái)統(tǒng)計(jì)切換路由到加載完成的時(shí)間。拿 Vue 舉例,一個(gè)可行的辦法就是切換路由時(shí),在路由的全局前置守衛(wèi) beforeEach 里獲取開(kāi)始時(shí)間,在組件的 mounted 鉤子里執(zhí)行 vm.$nextTick 函數(shù)來(lái)獲取組件的渲染完畢時(shí)間。
router.beforeEach((to, from, next) => { store.commit('setPageLoadedStartTime', new Date()) })
mounted() { this.$nextTick(() => { this.$store.commit('setPageLoadedTime', new Date() - this.$store.state.pageLoadedStartTime) }) }
除了性能和錯(cuò)誤監(jiān)控,其實(shí)我們還可以收集更多的信息。
用戶信息收集
navigator
使用 window.navigator 可以收集到用戶的設(shè)備信息,操作系統(tǒng),瀏覽器信息...
UV(Unique visitor)
是指通過(guò)互聯(lián)網(wǎng)瀏覽這個(gè)網(wǎng)頁(yè)的訪客,00:00-24:00 內(nèi)相同的設(shè)備訪問(wèn)只被計(jì)算一次。一天內(nèi)同個(gè)訪客多次訪問(wèn)僅計(jì)算一個(gè) UV。
在用戶訪問(wèn)網(wǎng)站時(shí),可以生成一個(gè)隨機(jī)字符串+時(shí)間日期,保存在本地。在網(wǎng)頁(yè)發(fā)生請(qǐng)求時(shí)(如果超過(guò)當(dāng)天24小時(shí),則重新生成),把這些參數(shù)傳到后端,后端利用這些信息生成 UV 統(tǒng)計(jì)報(bào)告。
PV(Page View)
即頁(yè)面瀏覽量或點(diǎn)擊量,用戶每 1 次對(duì)網(wǎng)站中的每個(gè)網(wǎng)頁(yè)訪問(wèn)均被記錄 1 個(gè)PV。用戶對(duì)同一頁(yè)面的多次訪問(wèn),訪問(wèn)量累計(jì),用以衡量網(wǎng)站用戶訪問(wèn)的網(wǎng)頁(yè)數(shù)量。
頁(yè)面停留時(shí)間
傳統(tǒng)網(wǎng)站
用戶在進(jìn)入 A 頁(yè)面時(shí),通過(guò)后臺(tái)請(qǐng)求把用戶進(jìn)入頁(yè)面的時(shí)間捎上。過(guò)了 10 分鐘,用戶進(jìn)入 B 頁(yè)面,這時(shí)后臺(tái)可以通過(guò)接口捎帶的參數(shù)可以判斷出用戶在 A 頁(yè)面停留了 10 分鐘。
SPA
可以利用 router 來(lái)獲取用戶停留時(shí)間,拿 Vue 舉例,通過(guò) router.beforeEach、destroyed 這兩個(gè)鉤子函數(shù)來(lái)獲取用戶停留該路由組件的時(shí)間。
瀏覽深度
通過(guò) document.documentElement.scrollTop 屬性以及屏幕高度,可以判斷用戶是否瀏覽完網(wǎng)站內(nèi)容。
頁(yè)面跳轉(zhuǎn)來(lái)源
通過(guò) document.referrer 屬性,可以知道用戶是從哪個(gè)網(wǎng)站跳轉(zhuǎn)而來(lái)。
小結(jié)
通過(guò)分析用戶數(shù)據(jù),我們可以了解到用戶的瀏覽習(xí)慣、愛(ài)好等等信息,想想真是恐怖,毫無(wú)隱私可言。
DEMO
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <script> function monitorInit() { const monitor = { // 數(shù)據(jù)上傳地址 url: '', // 性能信息 performance: {}, // 資源信息 resources: {}, // 錯(cuò)誤信息 errors: [], // 用戶信息 user: { // 屏幕寬度 screen: screen.width, // 屏幕高度 height: screen.height, // 瀏覽器平臺(tái) platform: navigator.platform, // 瀏覽器的用戶代理信息 userAgent: navigator.userAgent, // 瀏覽器用戶界面的語(yǔ)言 language: navigator.language, }, // 手動(dòng)添加錯(cuò)誤 addError(error) { const obj = {} const { type, msg, url, row, col } = error if (type) obj.type = type if (msg) obj.msg = msg if (url) obj.url = url if (row) obj.row = row if (col) obj.col = col obj.time = new Date().getTime() monitor.errors.push(obj) }, // 重置 monitor 對(duì)象 reset() { window.performance && window.performance.clearResourceTimings() monitor.performance = getPerformance() monitor.resources = getResources() monitor.errors = [] }, // 清空 error 信息 clearError() { monitor.errors = [] }, // 上傳監(jiān)控?cái)?shù)據(jù) upload() { // 自定義上傳 // axios.post({ // url: monitor.url, // data: { // performance, // resources, // errors, // user, // } // }) }, // 設(shè)置數(shù)據(jù)上傳地址 setURL(url) { monitor.url = url }, } // 獲取性能信息 const getPerformance = () => { if (!window.performance) return const timing = window.performance.timing const performance = { // 重定向耗時(shí) redirect: timing.redirectEnd - timing.redirectStart, // 白屏?xí)r間 whiteScreen: whiteScreen, // DOM 渲染耗時(shí) dom: timing.domComplete - timing.domLoading, // 頁(yè)面加載耗時(shí) load: timing.loadEventEnd - timing.navigationStart, // 頁(yè)面卸載耗時(shí) unload: timing.unloadEventEnd - timing.unloadEventStart, // 請(qǐng)求耗時(shí) request: timing.responseEnd - timing.requestStart, // 獲取性能信息時(shí)當(dāng)前時(shí)間 time: new Date().getTime(), } return performance } // 獲取資源信息 const getResources = () => { if (!window.performance) return const data = window.performance.getEntriesByType('resource') const resource = { xmlhttprequest: [], css: [], other: [], script: [], img: [], link: [], fetch: [], // 獲取資源信息時(shí)當(dāng)前時(shí)間 time: new Date().getTime(), } data.forEach(item => { const arry = resource[item.initiatorType] arry && arry.push({ // 資源的名稱(chēng) name: item.name, // 資源加載耗時(shí) duration: item.duration.toFixed(2), // 資源大小 size: item.transferSize, // 資源所用協(xié)議 protocol: item.nextHopProtocol, }) }) return resource } window.onload = () => { // 在瀏覽器空閑時(shí)間獲取性能及資源信息 https://developer.mozilla.org/zh-CN/docs/Web/API/Window/requestIdleCallback if (window.requestIdleCallback) { window.requestIdleCallback(() => { monitor.performance = getPerformance() monitor.resources = getResources() console.log('頁(yè)面性能信息') console.log(monitor.performance) console.log('頁(yè)面資源信息') console.log(monitor.resources) }) } else { setTimeout(() => { monitor.performance = getPerformance() monitor.resources = getResources() console.log('頁(yè)面性能信息') console.log(monitor.performance) console.log('頁(yè)面資源信息') console.log(monitor.resources) }, 0) } } // 捕獲資源加載失敗錯(cuò)誤 js css img... addEventListener('error', e => { const target = e.target if (target != window) { monitor.errors.push({ type: target.localName, url: target.src || target.href, msg: (target.src || target.href) + ' is load error', // 錯(cuò)誤發(fā)生的時(shí)間 time: new Date().getTime(), }) console.log('所有的錯(cuò)誤信息') console.log(monitor.errors) } }, true) // 監(jiān)聽(tīng) js 錯(cuò)誤 window.onerror = function(msg, url, row, col, error) { monitor.errors.push({ type: 'javascript', // 錯(cuò)誤類(lèi)型 row: row, // 發(fā)生錯(cuò)誤時(shí)的代碼行數(shù) col: col, // 發(fā)生錯(cuò)誤時(shí)的代碼列數(shù) msg: error && error.stack? error.stack : msg, // 錯(cuò)誤信息 url: url, // 錯(cuò)誤文件 time: new Date().getTime(), // 錯(cuò)誤發(fā)生的時(shí)間 }) console.log('所有的錯(cuò)誤信息') console.log(monitor.errors) } // 監(jiān)聽(tīng) promise 錯(cuò)誤 缺點(diǎn)是獲取不到行數(shù)數(shù)據(jù) addEventListener('unhandledrejection', e => { monitor.errors.push({ type: 'promise', msg: (e.reason && e.reason.msg) || e.reason || '', // 錯(cuò)誤發(fā)生的時(shí)間 time: new Date().getTime(), }) console.log('所有的錯(cuò)誤信息') console.log(monitor.errors) }) return monitor } const monitor = monitorInit() </script> <link rel="stylesheet" href="test.css"> <title>Document</title> </head> <body> <button class="btn1">錯(cuò)誤測(cè)試按鈕1</button> <button class="btn2">錯(cuò)誤測(cè)試按鈕2</button> <button class="btn3">錯(cuò)誤測(cè)試按鈕3</button> <img src="https://avatars3.githubusercontent.com/u/22117876?s=460&v=4" alt=""> <img src="test.png" alt=""> <script src="192.168.10.15/test.js"></script> <script> document.querySelector('.btn1').onclick = () => { setTimeout(() => { console.log(button) }, 0) } document.querySelector('.btn2').onclick = () => { new Promise((resolve, reject) => { reject({ msg: 'test.js promise is error' }) }) } document.querySelector('.btn3').onclick = () => { throw ('這是一個(gè)手動(dòng)扔出的錯(cuò)誤') } </script> </body> </html>
“如何進(jìn)行數(shù)據(jù)采集和數(shù)據(jù)上報(bào)”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。