亚洲VA久久久噜噜噜久久-精品国产性色无码av网站-亚洲午夜福利在线观看-小13箩利洗澡无码视频网站,日本特黄特色AAA大片免费,欧美日韩亚洲中文字幕二区,亚洲精品熟女国产

石家莊網(wǎng)站開發(fā) 石家莊網(wǎng)站開發(fā)公司

資訊動(dòng)態(tài)

察而思、思而行、行而后語、知行合一

【前端技術(shù)】前端實(shí)現(xiàn)監(jiān)控 SDK 的全面解析(二)

發(fā)布時(shí)間:2024-11-19 熱度:

  三、功能拆分

  (一)初始化

  初始化階段需要獲取用戶傳遞過來的相關(guān)參數(shù),接著調(diào)用初始化函數(shù)。在這個(gè)初始化函數(shù)里,能夠注入一些監(jiān)聽事件,以此來達(dá)成數(shù)據(jù)統(tǒng)計(jì)的功能。以下是具體的代碼實(shí)現(xiàn)示例及解析:

  javascript

  // 初始化配置

  function init(options) {

  // ------- 加載配置 ----------

  loadConfig(options);

  }

  // 加載配置

  export function loadConfig(options) {

  const {

  appId, // 系統(tǒng)id

  userId, // 用戶id

  reportUrl, // 后端url

  autoTracker, // 自動(dòng)埋點(diǎn)

  delay, // 延遲和合并上報(bào)的功能

  hashPage, // 是否hash錄有

  errorReport // 是否開啟錯(cuò)誤監(jiān)控

  } = options;

  // --------- appId ----------------

  if (appId) {

  window['_monitor_app_id_'] = appId;

  }

  // --------- userId ----------------

  if (userId) {

  window['_monitor_user_id_'] = userId;

  }

  // --------- 服務(wù)端地址 ----------------

  if (reportUrl) {

  window['_monitor_report_url_'] = reportUrl;

  }

  // -------- 合并上報(bào)的間隔 ------------

  if (delay) {

  window['_monitor_delay_'] = delay;

  }

  // --------- 是否開啟錯(cuò)誤監(jiān)控 ------------

  if (errorReport) {

  errorTrackerReport();

  }

  // --------- 是否開啟無痕埋點(diǎn) ----------

  if (autoTracker) {

  autoTrackerReport();

  }

  // ----------- 路由監(jiān)聽 --------------

  if (hashPage) {

  hashPageTrackerReport(); // hash路由上報(bào)

  } else {

  historyPageTrackerReport(); // history路由上報(bào)

  }

  }

  (二)錯(cuò)誤監(jiān)控

  前端錯(cuò)誤類型多樣,不同類型的錯(cuò)誤需要采用不同的捕獲方式來實(shí)現(xiàn)全面監(jiān)控。

  1. 語法錯(cuò)誤

  這類錯(cuò)誤通常在開發(fā)階段就能被發(fā)現(xiàn),例如拼寫錯(cuò)誤、符號(hào)使用錯(cuò)誤等情況。語法錯(cuò)誤沒辦法通過 try{}catch{} 進(jìn)行捕獲,因?yàn)檎T陂_發(fā)流程中就會(huì)被排查出來,基本不會(huì)發(fā)布到線上環(huán)境。

  2. 同步錯(cuò)誤

  在 JavaScript 同步執(zhí)行過程中產(chǎn)生的錯(cuò)誤屬于同步錯(cuò)誤,像變量未定義這類情況,此類錯(cuò)誤是可以被 try-catch 語句捕獲到的。

  3. 異步錯(cuò)誤

  在諸如 setTimeout 等函數(shù)執(zhí)行中出現(xiàn)的錯(cuò)誤就是異步錯(cuò)誤,它無法被 try-catch 捕獲,但可以利用 Window.onerror 來進(jìn)行捕獲處理,相較而言這種方式要比 try-catch 方便許多。

  4. Promise 錯(cuò)誤

  在 Promise 中,如果使用 catch 語句是可以捕獲到異步錯(cuò)誤的,然而要是沒寫 catch 的話,在 Window.onerror 里是沒辦法捕獲到這類錯(cuò)誤的。對(duì)此,可以在全局添加 unhandledrejection 監(jiān)聽來捕獲那些沒被捕獲到的 Promise 錯(cuò)誤。

  5. 資源加載錯(cuò)誤

  指的是一些資源文件獲取失敗的情況,一般通過 Window.addEventListener 來進(jìn)行捕獲操作。

  綜合來看,SDK 監(jiān)控錯(cuò)誤主要圍繞以上這些類型來實(shí)現(xiàn),try-catch 用于在可預(yù)見的情形下監(jiān)控特定錯(cuò)誤,Window.onerror 主要負(fù)責(zé)捕獲那些預(yù)料之外的錯(cuò)誤(比如異步錯(cuò)誤),但對(duì)于 Promise 錯(cuò)誤和網(wǎng)絡(luò)錯(cuò)誤無法單純依靠它們捕獲,所以需要借助 Window.unhandledrejection 監(jiān)聽捕獲 Promise 錯(cuò)誤,通過 error 監(jiān)聽捕獲資源加載錯(cuò)誤,以此達(dá)成對(duì)各類型錯(cuò)誤的全面覆蓋。

2023082517472366945.jpg

  (三)用戶埋點(diǎn)統(tǒng)計(jì)

  埋點(diǎn)是用于監(jiān)控用戶在應(yīng)用上的各種動(dòng)作表現(xiàn)的一種手段。

  1. 手動(dòng)埋點(diǎn)

  需要手動(dòng)在代碼中添加相關(guān)的埋點(diǎn)代碼,比如當(dāng)用戶點(diǎn)擊某個(gè)按鈕或者提交一個(gè)表單時(shí),就在按鈕點(diǎn)擊事件以及提交事件中添加對(duì)應(yīng)的埋點(diǎn)代碼。其優(yōu)點(diǎn)在于可控性較強(qiáng),能夠根據(jù)需求自定義上報(bào)具體的數(shù)據(jù)內(nèi)容;但缺點(diǎn)也很明顯,就是對(duì)業(yè)務(wù)代碼的侵入性較大,如果需要在很多地方進(jìn)行埋點(diǎn)操作,那就得逐個(gè)去添加代碼了。

  2. 自動(dòng)埋點(diǎn)

  自動(dòng)埋點(diǎn)很好地解決了手動(dòng)埋點(diǎn)的缺點(diǎn),實(shí)現(xiàn)了無需侵入業(yè)務(wù)代碼就能在應(yīng)用里添加埋點(diǎn)監(jiān)控的功能。不過它也存在不足,只能上報(bào)基本的行為交互信息,沒辦法上報(bào)自定義的數(shù)據(jù),而且只要頁面中有點(diǎn)擊操作,就會(huì)向服務(wù)器上報(bào),這可能導(dǎo)致上報(bào)次數(shù)過多,給服務(wù)器帶來較大壓力。同時(shí)需要注意,如果在 click 事件中阻止了冒泡行為,自動(dòng)埋點(diǎn)是無法捕獲到的,這種情況下就需要進(jìn)行手動(dòng)埋點(diǎn)上報(bào),以確保上報(bào)的全面覆蓋。

  (四)PV 統(tǒng)計(jì)

  PV 即頁面瀏覽量,表示頁面被訪問的次數(shù)。對(duì)于非 SPA 頁面,只需通過監(jiān)聽 onload 事件就能統(tǒng)計(jì)頁面的 PV 了。但在 SPA 頁面中,路由的切換主要依靠前端來實(shí)現(xiàn),而且單頁面切換又分為 hash 路由和 history 路由,這兩種路由的實(shí)現(xiàn)原理不一樣,所以要分別針對(duì)它們實(shí)現(xiàn)不同的數(shù)據(jù)采集方式。

  1. history 路由

  history 路由是依賴全局對(duì)象 history 來實(shí)現(xiàn)的,它包含諸如 history.back()(返回上一頁,對(duì)應(yīng)瀏覽器回退操作)、history.forward()(前進(jìn)一頁,即瀏覽器前進(jìn)操作)、history.go()(跳轉(zhuǎn)歷史中某一頁)、history.pushState()(添加新記錄)、history.replaceState()(修改當(dāng)前記錄)等方法。其中 pushState 和 replaceState 這兩個(gè)方法不能被 popstate 監(jiān)聽到,因此需要對(duì)這兩個(gè)方法進(jìn)行重寫,并添加自定義事件監(jiān)聽來實(shí)現(xiàn)數(shù)據(jù)采集,以下是具體的代碼實(shí)現(xiàn)示例及解析:

  javascript

  import { lazyReport } from './report';

  // history路由監(jiān)聽

  export function historyPageTrackerReport() {

  let beforeTime = Date.now(); // 進(jìn)入頁面的時(shí)間

  let beforePage = ''; // 上一個(gè)頁面

  // 獲取在某個(gè)頁面的停留時(shí)間

  function getStayTime() {

  let curTime = Date.now();

  let stayTime = curTime - beforeTime;

  beforeTime = curTime;

  return stayTime;

  }

  // 重寫pushState和replaceState方法

  const createHistoryEvent = function (name) {

  // 拿到原來的處理方法

  const origin = window.history[name];

  return function(event) {

  let res = origin.apply(this, arguments);

  let e = new Event(name);

  e.arguments = arguments;

  window.dispatchEvent(e);

  return res;

  };

  };

  // history.pushState

  window.addEventListener('pushState', function () {

  listener()

  });

  // history.replaceState

  window.addEventListener('replaceState', function () {

  listener()

  });

  window.history.pushState = createHistoryEvent('pushState');

  window.history.replaceState = createHistoryEvent('replaceState');

  function listener() {

  const stayTime = getStayTime(); // 停留時(shí)間

  const currentPage = window.location.href; // 頁面路徑

  lazyReport('visit', {

  stayTime,

  page: beforePage,

  })

  beforePage = currentPage;

  }

  // 頁面load監(jiān)聽

  window.addEventListener('load', function () {

  // beforePage = location.href;

  listener()

  });

  // unload監(jiān)聽

  window.addEventListener('unload', function () {

  listener()

  });

  // history.go()、history.back()、history.forward() 監(jiān)聽

  window.addEventListener('popstate', function () {

  listener()

  });

  }

  2. hash 路由

  在 hash 路由中,url 里的 hash 值發(fā)生變化時(shí)會(huì)觸發(fā) hashChange 的監(jiān)聽,所以只需在全局添加一個(gè)監(jiān)聽函數(shù),然后在這個(gè)函數(shù)里實(shí)現(xiàn)數(shù)據(jù)采集上報(bào)就可以了。不過在 React 和 Vue 等框架中,hash 路由的跳轉(zhuǎn)有時(shí)候是通過 pushState 實(shí)現(xiàn)的,所以還需要加上對(duì) pushState 的監(jiān)聽,以下是具體代碼示例及解析:

  javascript

  // hash路由監(jiān)聽

  export function hashPageTrackerReport() {

  let beforeTime = Date.now(); // 進(jìn)入頁面的時(shí)間

  let beforePage = ''; // 上一個(gè)頁面

  function getStayTime() {

  let curTime = Date.now();

  let stayTime = curTime - beforeTime; //當(dāng)前時(shí)間 - 進(jìn)入時(shí)間

  beforeTime = curTime;

  return stayTime;

  }

  function listener() {

  const stayTime = getStayTime();

  const currentPage = window.location.href;

  lazyReport('visit', {

  stayTime,

  page: beforePage,

  })

  beforePage = currentPage;

  }

  // hash路由監(jiān)聽

  window.addEventListener('hashchange', function () {

  listener()

  });

  // 頁面load監(jiān)聽

  window.addEventListener('load', function () {

  listener()

  });

  const createHistoryEvent = function (name) {

  const origin = window.history[name];

  return function(event) {

  //自定義事件

  let res = origin.apply(this, arguments);

  let e = new Event(name);

  e.arguments = arguments;

  window.dispatchEvent(e);

  return res;

  };

  };

  window.history.pushState = createHistoryEvent('pushState');

  // history.pushState

  window.addEventListener('pushState', function () {

  listener()

  });

  }

  (五)UV 統(tǒng)計(jì)

  UV 統(tǒng)計(jì)相對(duì)來說較為簡(jiǎn)單,只需在 SDK 初始化時(shí)上報(bào)一條消息即可完成相關(guān)數(shù)據(jù)的收集。

  四、數(shù)據(jù)上報(bào)方式

  (一)xhr 接口請(qǐng)求

  采用接口請(qǐng)求的方式來上報(bào)數(shù)據(jù),其原理和其他業(yè)務(wù)請(qǐng)求類似,只不過傳遞的數(shù)據(jù)是埋點(diǎn)相關(guān)的數(shù)據(jù)。但這種方式存在一些問題,一方面,通常公司里處理埋點(diǎn)的服務(wù)器和處理業(yè)務(wù)邏輯的服務(wù)器并非同一臺(tái),所以往往需要手動(dòng)去解決跨域問題;另一方面,如果在上報(bào)過程中出現(xiàn)頁面刷新或者重新打開頁面的情況,很可能會(huì)造成埋點(diǎn)數(shù)據(jù)的缺失,因此傳統(tǒng)的 xhr 接口請(qǐng)求方式在適應(yīng)埋點(diǎn)需求方面存在一定局限性。

  (二)img 標(biāo)簽

  利用 img 標(biāo)簽上報(bào)數(shù)據(jù),是將埋點(diǎn)數(shù)據(jù)偽裝成圖片 url 的請(qǐng)求形式,這樣做的好處是能夠避免跨域問題。然而,瀏覽器對(duì) url 的長(zhǎng)度是有限制的,所以這種方式不太適合大數(shù)據(jù)量的上報(bào),而且同樣存在刷新或重新打開頁面時(shí)數(shù)據(jù)丟失的問題。

  (三)sendBeacon

  這種上報(bào)方式不會(huì)出現(xiàn)跨域問題,也不存在刷新或重新打開頁面導(dǎo)致的數(shù)據(jù)丟失情況,但它有兼容性方面的問題。在日常開發(fā)中,通常會(huì)采用 sendBeacon 上報(bào)和 img 標(biāo)簽上報(bào)相結(jié)合的方式,以此來兼顧各種情況,確保數(shù)據(jù)上報(bào)的有效性和穩(wěn)定性。以下是具體的上報(bào)函數(shù)代碼示例:

  javascript

  // 上報(bào)

  export function report(data) {

  const url = window['_monitor_report_url_'];

  // ------- fetch方式上報(bào) -------

  // 跨域問題

  // fetch(url, {

  // method: 'POST',

  // body: JSON.stringify(data),

  // headers: {

  // 'Content-Type': 'application/json',

  // },

  // }).then(res => {

  // console.log(res);

  // }).catch(err => {

  // console.error(err);

  // })

  // ------- navigator/img方式上報(bào) -------

  // 不會(huì)有跨域問題

  if (navigator.sendBeacon) { // 支持sendBeacon的瀏覽器

  navigator.sendBeacon(url, JSON.stringify(data));

  } else { // 不支持sendBeacon的瀏覽器

  let oImage = new Image();

  oImage.src = `${url}?logs=${data}`;

  }

  clearCache();

  }

  通過上述對(duì)前端實(shí)現(xiàn)監(jiān)控 SDK 的介紹,涵蓋了能拆分到數(shù)據(jù)上報(bào)環(huán)節(jié),旨在幫助開發(fā)人員更好地構(gòu)建和運(yùn)用監(jiān)控系統(tǒng),以保障前端應(yīng)用的穩(wěn)定運(yùn)行以及對(duì)用戶行為等方面的有效洞察。


聯(lián)系尚武科技
客戶服務(wù)
石家莊APP開發(fā)
400-666-4864
為您提供售前購(gòu)買咨詢、解決方案推薦等1V1服務(wù)!
技術(shù)支持及售后
石家莊APP開發(fā)公司
0311-83796180
為您提供從產(chǎn)品到服務(wù)的全面技術(shù)支持 !
客戶服務(wù)
石家莊小程序開發(fā)
石家莊小程序開發(fā)公司
加我企業(yè)微信
為您提供售前購(gòu)買咨詢、
解決方案推薦等1V1服務(wù)!
石家莊網(wǎng)站建設(shè)公司
咨詢相關(guān)問題或預(yù)約面談,可以通過以下方式與我們聯(lián)系。
石家莊網(wǎng)站制作
在線聯(lián)系:
石家莊Web開發(fā)
石家莊軟件開發(fā)
石家莊軟件開發(fā)公司
ADD/地址:
河北·石家莊
新華區(qū)西三莊大街86號(hào)河北互聯(lián)網(wǎng)大廈B座二層
Copyright ? 2008-2025尚武科技 保留所有權(quán)利。 冀ICP備12011207號(hào)-2 石家莊網(wǎng)站開發(fā)冀公網(wǎng)安備 13010502001294號(hào)《互聯(lián)網(wǎng)平臺(tái)公約協(xié)議》
Copyright ? 2025 www.dldhf.com, Inc. All rights reserved