前端埋点技术分享

243 阅读2分钟

1.无埋点技术

提高数据采集效率

颠覆传统数据采集流程漫长、耗时耗力的弊病 无需埋点,一行代码,一次部署,秒级出图 降低工程成本,提高数据分析效率

轻松进行跨平台的数据分析

支持 Web、iOS、Android、H5 等多平台 多维度、自定义灵活分析 上手简单,功能强大,一键出报表

无埋点+埋点,双模式高效、全面采集数据

精确采集业务数据,覆盖完整用户生命周期 支持埋点采集用户、事件、页面、转化等变量数据

2.无埋点给不同人群带来便利

运营和市场

  • 按需搭建数据图表,运营数据尽在掌握
  • 提高渠道回报率,降低获客成本
  • 优化用户体验,提高留存

产品经理

  • 监控产品核心指标,获得业务洞察
  • 提高产品转化率,优化用户体验
  • 提高产品活跃度,提升产品整体留存

管理者和开发

  • 对产品情况一清二楚
  • 监控异常情况,拆解问题

3.web sdk 文档介绍

juejin.cn/post/693497…

4.JINLINS.utm 源码解析

1.UTMID 取值规则

JINLINS.utmID = function (id) {
    if (!id) {
        if (JINLINS._utmID) {
            return JINLINS._utmID
        }
        var utmParts = (window.WDNative && window.WDNative.utm || JINLINS.getQuery("utm")).split(".", 4)
        utmParts.length = 4
        var utmPartsFromBody = (document.documentElement.getAttribute("data-utm-id") || "").split(".", 4)
        while (utmPartsFromBody.length < 4) utmPartsFromBody.unshift("")
        utmParts[0] = utmParts[0] || utmPartsFromBody[0] || ""
        utmParts[1] = utmParts[1] || utmPartsFromBody[1] || location.hostname.replace(/\./g, "-")
        var path = location.href.replace(/^.*?:\/\/[^/]*/, "").replace(/\?.*#/i, "#").replace(/\?.*$/i, "").replace(/\./g, "-").replace(/^\//, "");
        var slash = path.indexOf("/")
        utmParts[2] = utmParts[2] || utmPartsFromBody[2] || path.slice(0, slash)
        utmParts[3] = utmParts[3] || utmPartsFromBody[3] || path.slice(slash + 1)
        return JINLINS._utmID = utmParts.join(".")
    }
    JINLINS._utmID = id
}

2.PATH 取值规则

JINLINS.utmPath = function (node) {
    if (node.id && document.getElementById(node.id) === node) {
        return "#" + node.id
    }
    if (node.className && document.getElementsByClassName) {
        var classNames = node.className.split(/\s+/, 1)
        for (var i = 0; i < classNames.length; i++) {
            if (document.getElementsByClassName(classNames[i]).length === 1) {
                return "." + classNames[i]
            }
        }
    }
    if (document.getElementsByTagName(node.tagName).length === 1) {
        return node.tagName
    }
    var path = node.id ? "#" + node.id : node.className ? "." + node.className.replace(/\s.*$/, "") : node.tagName
    if (node.parentNode) {
        var index = 0
        for (var n = node.parentNode.firstChild; n != node; n = n.nextSibling) {
            if (n.tagName == node.tagName) {
                index++
            }
        }
        return JINLINS.utmPath(node.parentNode) + "/" + path + "[" + index + "]"
    }
    return path
}

3.JINLINS.utmFlush 数据上报

JINLINS.utmFlush = function (useBeacon) {
    JINLINS._utmTimer = 0
    var utm = _hashState ? _hashUtmId : JINLINS.utmID()
    _hashState = false;
    var vid = JINLINS.utmVID()
    var branch = window.WDNative && window.WDNative.branch || JINLINS.utmGet("utm_branch")
    var logs = JINLINS._utmLogs
    var isPrd = (window.WDNative && window.WDNative.env) ? (window.WDNative.env == 'pre' || window.WDNative.env == 'prd') : (!/jinlins\.com|jinlins\.work/.test(location.host))
    while (logs.length) {
        var url = (/https[:]?/.test(location.protocol) ? "https:" : "http:") + (isPrd ? "//apprd.jinlins.com.cn/receive_data/v1/action/UtmCustomAction?utm=" : "//reveivedatawd.jinlins.com/utmAction/doReveive?utm=") + encodeURIComponent(utm)
        if (vid) url += "&vid=" + encodeURIComponent(vid)
        else url += "&callback=JINLINS.utmVID"
        if (branch) url += "&branch=" + encodeURIComponent(branch)
        url += "&logs=[" + logs.shift()
        while (logs.length && url.length + logs[0].length < 7206) {
            url += "," + logs.shift()
        }
        url += "]"
        url = url.replace(/\n|\r|\t/g, '')
        if (useBeacon === true) {
            if (navigator.sendBeacon) {
                navigator.sendBeacon(url)
            } else {
                var xhr = new XMLHttpRequest()
                xhr.open("GET", url, true)
                xhr.send(null)
            }
        } else {
            var script = document.createElement("script")
            script.async = true
            script.setAttribute("crossorigin", "anonymous")
            script.onload = script.onreadystatechange = function () {
                if (!script.readyState || script.readyState === "loaded" || script.readyState === "complete") {
                    script.onload = script.onreadystatechange = null
                    script.parentNode.removeChild(script)
                }
            }
            script.src = url
            var firstScript = document.getElementsByTagName("script")[0]
            firstScript.parentNode.insertBefore(script, firstScript)
        }
    }
}