日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

web 埋点实现原理了解一下

發布時間:2025/3/20 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 web 埋点实现原理了解一下 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

埋點,是網站分析的一種常用的數據采集方法。我們主要用來采集用戶行為數據(例如頁面訪問路徑,點擊了什么元素)進行數據分析,從而讓運營同學更加合理的安排運營計劃。現在市面上有很多第三方埋點服務商,百度統計,友盟,growingIO 等大家應該都不太陌生,大多情況下大家都只是使用,最近我研究了下 web 埋點,你要不要了解下。

現有埋點三大類型

用戶行為分析是一個大系統,一個典型的數據平臺。由用戶數據采集,用戶行為建模分析,可視化報表展示幾個模塊構成。現有的埋點采集方案可以大致被分為三種,手動埋點,可視化埋點,無埋點
  • 手動埋點
    手動代碼埋點比較常見,需要調用埋點的業務方在需要采集數據的地方調用埋點的方法。優點是流量可控,業務方可以根據需要在任意地點任意場景進行數據采集,采集信息也完全由業務方來控制。這樣的有點也帶來了一些弊端,需要業務方來寫死方法,如果采集方案變了,業務方也需要重新修改代碼,重新發布。
  • 可視化埋點
    可是化埋點是近今年的埋點趨勢,很多大廠自己的數據埋點部門也都開始做這塊。優點是業務方工作量少,缺點則是技術上推廣和實現起來有點難(業務方前端代碼規范是個大前提)。阿里的活動頁很多都是運營通過可視化的界面拖拽配置實現,這些活動控件元素都帶有唯一標識。通過埋點配置后臺,將元素與要采集事件關聯起來,可以自動生成埋點代碼嵌入到頁面中。
  • 無埋點
    無埋點則是前端自動采集全部事件,上報埋點數據,由后端來過濾和計算出有用的數據,優點是前端只要加載埋點腳本。缺點是流量和采集的數據過于龐大,服務器性能壓力山大,主流的 GrowingIO 就是這種實現方案。
  • 我們暫時放棄可視化埋點的實現,在 手動埋點 和 無埋點 上進行了嘗試,為了便于描述,下文我會稱采集腳本為 SDK。

    思考幾個問題

    埋點開發需要考慮很多內容,貫穿著不輕易動手寫代碼的原則,我們在開發前先思考下面這幾個問題
  • 我們要采集什么內容,進行哪些采集接口的約定
  • 業務方通過什么方式來調用我們的采集腳本
  • 手動埋點:SDK 需要封裝一個方法給業務方進行調用,傳參方式業務方可控
  • 無埋點:考慮到數據量對于服務器的壓力,我們需要對無埋點進行開關配置,可以配置進行哪些元素進行無埋點采集
  • 用戶標識:游客用戶和登錄用戶的采集數據怎么進行區分關聯
  • 設備Id:用戶通過瀏覽器來訪問 web 頁面,設備Id需要存儲在瀏覽器上,同一個用戶訪問不同的業務方網站,設備Id要保持一樣,怎么實現
  • 單頁面應用:現在流行的單頁面應用和普通 web 頁面的數據采集是否有差異
  • 混合應用:app 與 h5 的混合應用我們要怎么進行通訊
  • 我們要采集什么內容,進行哪些采集接口的約定

    第一期我們先實現對 PV(即頁面瀏覽量或點擊量) 、UV(一天內同個訪客多次訪問) 、點擊量、用戶的訪問路徑的基礎指標的采集。精細化分析的流量轉化需要和業務相關,需要和數據分析方做約定,我們預留擴展。所以我們的采集接口需要進行以下的約定

    {"header":{ // HTTP 頭部"X-Device-Id":" 550e8400-e29b-41d4-a716-446655440000", //設備ID,用來區分用戶設備"X-Source-Url":"https://www.baidu.com/", //源地址,關聯用戶的整個操作流程,用于用戶行為路徑分析,例如登錄,到首頁,進入商品詳情,退出這一整個完整的路徑"X-Current-Url":"", //當前地址,用戶行為發生的頁面"X-User-Id":"",//用戶ID,統計登錄用戶行為},"body":[{ // HTTP Body體"PageSessionID":"", //頁面標識ID,用來區分頁面事件,例如加載和離開我們會發兩個事件,這個標識可以讓我們知道這個事件是發生在一個頁面上"Event":"loaded", //事件類型,區分用戶行為事件"PageTitle": "埋點測試頁", //頁面標題,直觀看到用戶訪問頁面"CurrentTime": “1517798922201”, //事件發生的時間"ExtraInfo": {} //擴展字段,對具體業務分析的傳參}] }

    以上就是我們現在約定好了的通用的事件采集的接口,所傳的參數基本上會根據采集事件的不同而發生變化。但是在用戶的整一個訪問行為中,用戶的設備是不會變化的,如果你想采集設備信息可以重新約定一個接口,在整個采集開始之前發送設備信息,這樣可以避免在事件采集接口上重復采集固定數據。

    {"header":{ // HTTP 頭部"X-Device-Id" :"550e8400-e29b-41d4-a716-446655440000" , // 設備id},"body":{ // HTTP Body體"DeviceType": "web" , //設備類型"ScreenWide" : 768 , // 屏幕寬"ScreenHigh": 1366 , // 屏幕高"Language": "zh-cn" //語言} }

    業務方通過什么方式來調用我們的采集腳本

    埋點應該讓調用的業務方,盡可能少有工作量,最好是什么都不用做,?,但是實現起來有點難額。我們采用的方案是讓業務方在代碼里通過 script 腳本來引用我們的 SDK ,業務方只要配置一些需要的參數進行埋點定制(?我們講到過的無埋點的流量控制),然后什么都不做就可以進行基礎數據的采集。

    (function() {var collect = document.createElement('script');collect.type = 'text/javascript';collect.async = true;collect.src = 'http://collect.trc.com/index.js';var s = document.getElementsByTagName('script')[0];s.parentNode.insertBefore(collect, s);})();//用戶自定義要進行無埋點采集的元素,如果不進行無埋點采集,可以不配置var _XT = [];_XT.push(['Target','div']);

    手動埋點:SDK

    如果業務方需要采集更多業務定制的數據,可以調用我們暴露出的方法進行采集

    //自定義事件sdk.dispatch('customEvent',{extraInfo:'自定義事件的額外信息'})

    游客與用戶關聯

    我們使用 userId 來做用戶標識,同一個設備的用戶,從游客用戶切換到登錄用戶,如果我們要把他們關聯起來,需要有一個設備Id 做關聯

    web 設備Id

    用戶通過瀏覽器來訪問 web 頁面,設備Id需要存儲在瀏覽器上,同一個用戶訪問不同的業務方網站,設備Id要保持一樣。web 變量存儲,我們第一時間想到的就是 cookie,sessionStorage,localStorage,但是這3種存儲方式都和訪問資源的域名相關。我們總不能每次訪問一個網站就新建一個設備指紋吧,所以我們需要通過一個方法來跨域共享設備指紋

    我們想到的方案是,通過嵌套 iframe 加載一個靜態頁面,在 iframe 上加載的域名上存儲設備id,通過跨域共享變量獲取設備id,共享變量的原理是采用了iframe 的 contentWindow通訊,通過 postMessage 獲取事件狀態,調用封裝好的回調函數進行數據處理具體的實現方式

    //web 應用,通過嵌入 iframe 進行跨域 cookie 通訊,設置設備id,collect.setIframe = function () {var that = thisvar iframe = document.createElement('iframe')iframe.id = "frame",iframe.src = 'http://collectiframe.trc.com' // 配置域名代理,目的是讓開發測試生產環境代碼一致iframe.style.display='none' //iframe 設置的目的是用來生成固定的設備id,不展示document.body.appendChild(iframe)iframe.onload = function () {iframe.contentWindow.postMessage('loaded','*');}//監聽message事件,iframe 加載完成,獲取設備id ,進行相關的數據采集helper.on(window,"message",function(event){that.deviceId = event.data.deviceIdif(event.data && event.data.type == 'loaded'){that.sendDevice(that.getDevice(), that.deviceUrl);setTimeout(function () {that.send(that.beforeload)that.send(that.loaded)},1000)}})}

    iframe 與 SDK 通訊

    function receiveMessageFromIndex ( event ) {getDeviceInfo() // 獲取設備信息var data = {deviceId: _deviceId,type:event.data}event.source.postMessage(data, '*'); // 將設備信息發送給 SDK }//監聽message事件 if(window.addEventListener){window.addEventListener("message", receiveMessageFromIndex, false); }else{window.attachEvent("onmessage", receiveMessageFromIndex, false)

    如果你想知道可以看我的另一篇博客 web 瀏覽器指紋跨域共享

    單頁面應用:現在流行的單頁面應用和普通 web 頁面的數據采集是否有差異

    我們知道單頁面應用都是無刷新的頁面加載,所以我們在頁面跳轉的處理和我們的普通的頁面會有所不同。單頁面應用的路由插件運用了 window 自帶的無刷新修改用戶瀏覽記錄的方法,pushState 和 replaceState。

    window 的 history 對象 提供了兩個方法,能夠無刷新的修改用戶的瀏覽記錄,pushSate,和 replaceState,區別的 pushState 在用戶訪問頁面后面添加一個訪問記錄, replaceState 則是直接替換了當前訪問記錄,所以我們只要改寫 history 的方法,在方法執行前執行我們的采集方法就能實現對單頁面應用的頁面跳轉事件的采集了

    // 改寫思路:拷貝 window 默認的 replaceState 函數,重寫 history.replaceState 在方法里插入我們的采集行為,在重寫的 replaceState 方法最后調用,window 默認的 replaceState 方法collect = {}collect.onPushStateCallback : function(){} // 自定義的采集方法(function(history){var replaceState = history.replaceState; // 存儲原生 replaceStatehistory.replaceState = function(state, param) { // 改寫 replaceStatevar url = arguments[2];if (typeof collect.onPushStateCallback == "function") {collect.onPushStateCallback({state: state, param: param, url: url}); //自定義的采集行為方法}return replaceState.apply(history, arguments); // 調用原生的 replaceState};})(window.history);

    這塊介紹起來也比較的復雜,如果你想了解更多,可以看我的另一篇博客你需要知道的單頁面路由實現原理

    混合應用:app 與 h5 的混合應用我們要怎么進行通訊

    現在大部分的應用都不是純原生的應用, app 與 h5 的混合的應用是現在的一種主流。

    純 web 數據采集我們考慮到前端存儲數據容易丟失,我們在每一次事件觸發的時候都用采集接口傳輸采集到的數據。考慮到現在很多用戶的手機會有流量管家的軟件監控,如果在 App 中 h5 還是采集到數據就傳輸給服務端,很有可能會讓流量管家檢測到,給用戶報警,從而使得用戶不再信任你的 App , 所以我們在用戶操作的時候將數據傳給 app 端,存儲到 app。用戶切換應用到后臺的時候,通過 app 端的 SDK 打包傳輸到服務器,我們給 app 提供的方法封裝了一個適配器

    // app 與 h5 混合應用,直接將數信息發給 app collect.saveEvent = function (jsonString) {collect.dcpDeviceType && setTimeout(function () {if(collect.dcpDeviceType=='android'){android.saveEvent(jsonString)} else {window.webkit && window.webkit.messageHandlers ? window.webkit.messageHandlers.nativeBridge.postMessage(jsonString) : window.postBridgeMessage(jsonString)}},1000)}

    實現思路

    通過上面幾個問題的思考,我們對埋點的實現大致已經有了一些想法,我們使用思維導圖來還原下我們即將要做的事情,圖片記得放大看哦,太小了可能看不清。

    我們需要暴露給業務方調用的方法


    我們需要處理的事件類型

    SDK 的基本實現思路

    我們來看下幾個核心代碼的實現

    工具方法

    我們定義了幾個工具方法,提高開發的幸福指數 ?

    var helper = {};// 生成一個唯一的標識,pageSessionId (用這個變量來關聯開始加載、加載完成、離開頁面的事件,計算出頁面加菜時間,停留時間)helper.uuid = function(){}// 元素綁定事件監聽,兼容瀏覽器到IE8helper.on = function(){}//元素移除事件監聽的適配器函數,兼容瀏覽器到IE8helper.remove = function(){}//將json轉為字符串,事件傳輸的參數類型轉化helper.changeJSON2Query = function(){}//將相對路徑解析成文檔全路徑helper.normalize = function(){}

    采集邏輯

    var collect = {deviceUrl:'http://collect.trc.com/rest/collect/device/h5/v1',eventUrl:'http://collect.trc.com/rest/collect/event/h5/v1',isuploadUrl:'http://collect.trc.com/rest/collect/isupload/app/v1',parmas:{ ExtraInfo:{} },device:{}};//獲取埋點配置collect.setParames = function(){}//更新訪問路徑及頁面信息collect.updatePageInfo = function(){}//獲取事件參數collect.getParames = function(){}//獲取設備信息collect.getDevice = function(){}//事件采集collect.send = function(){}//設備采集collect.sendDevice = function(){}//判斷才否采集,埋點采集的開關collect.isupload = function(){1. 判斷是否采集,不采集就注銷事件監聽(項目中區分游客身份和用戶身份的采集情況,這個方法會被判斷兩次)2. 采集則判斷是否已經采集過a.已經采集過不做任何操作b.沒有采集過添加事件監聽3. 判斷是 混合應用還是純 web 應用a.如果是web 應用,調用 collect.setIframe 設置 iframeb.如果是混合應用 將開始加載和加載完成事件傳輸給 app}//點擊事件處理函數collect.clickHandler = function(){}//離開頁面的事件處理函數collect.beforeUnloadHandler = function(){}//頁面回退事件處理函數collect.onPopStateHandler = function(){}//系統事件初始化,注冊離開事件,瀏覽器后退事件collect.event = function(){}//獲取記錄開始加載數據信息collect.getBeforeload = function(){}//存儲加載完成,獲取設備類型,記錄加載完成信息collect.onload = function(){1. 判斷cookie是否有存設備類型信息,有表示混合應用2. 采集加載完成時間等信息3. 調用 collect.isupload 判斷是否進行采集}//web 應用,通過嵌入 iframe 進行跨域 cookie 通訊,設置設備idcollect.setIframe = function(){}//app 與 h5 混合應用,直接將數信息發給 app,判斷設備類型做原生方法適配器collect.saveEvent = function(){}//采集自定義事件類型collect.dispatch = function(){}//將參數 userId 存入sessionStoragecollect.storeUserId = function(){}//采集H5信息,如果是混合應用,將采集到的信息發送給 app 端collect.saveEventInfo = function(){}//頁面初始化調用方法collect.init = function(){1. 獲取開始加載的采集信息2. 獲取 SDK 配置信息,設備信息3. 改寫 history 兩個方法,單頁面應用頁面跳轉前調用我們自己的方法4. 頁面加載完成,調用 collect.onload 方法}collect.init(); // 初始化//暴露給業務方調用的方法return {dispatch:collect.dispatch,storeUserId:collect.storeUserId,}

    擴展

    ?就是我這段時間研究的成果了,代碼的篇幅比較長,就不放在博客里了,感興趣的同學可以加我微信進行交流,或則在文章下面留言,也歡迎大家給我提意見,幫忙優化 ?。

    web 瀏覽器指紋跨域共享

    你需要知道的單頁面路由實現原理

    數據埋點是什么?設置埋點的意義是什么?

    數據采集與埋點

    美團點評前端無痕埋點實踐

    如何清楚易懂的解釋“UV和PV"的定義

    總結

    以上是生活随笔為你收集整理的web 埋点实现原理了解一下的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。