93 lines
2.5 KiB
JavaScript
93 lines
2.5 KiB
JavaScript
/**
|
|
* 全站渠道首次归因。
|
|
* 与落地页约定一致,按 dc、ch、pc 顺序识别,并同步到 localStorage 与 cookie。
|
|
*/
|
|
(function (global) {
|
|
"use strict";
|
|
|
|
var STORAGE_KEY = "channel";
|
|
var QUERY_KEYS = ["dc", "ch", "pc"];
|
|
|
|
function clean(value) {
|
|
return String(value == null ? "" : value).trim();
|
|
}
|
|
|
|
function readStorage() {
|
|
try {
|
|
return clean(global.localStorage.getItem(STORAGE_KEY));
|
|
} catch (e) {
|
|
return "";
|
|
}
|
|
}
|
|
|
|
function writeStorage(channel) {
|
|
try {
|
|
global.localStorage.setItem(STORAGE_KEY, channel);
|
|
} catch (e) {}
|
|
}
|
|
|
|
function readCookie() {
|
|
try {
|
|
var match = document.cookie.match(/(?:^|;\s*)channel=([^;]*)/);
|
|
return match ? clean(decodeURIComponent(match[1])) : "";
|
|
} catch (e) {
|
|
return "";
|
|
}
|
|
}
|
|
|
|
function writeCookie(channel) {
|
|
try {
|
|
var secure = global.location && global.location.protocol === "https:" ? "; Secure" : "";
|
|
document.cookie =
|
|
STORAGE_KEY +
|
|
"=" +
|
|
encodeURIComponent(channel) +
|
|
"; Path=/; Max-Age=31536000; SameSite=Lax" +
|
|
secure;
|
|
} catch (e) {}
|
|
}
|
|
|
|
function readQuery() {
|
|
try {
|
|
var params = new URLSearchParams(global.location.search || "");
|
|
for (var i = 0; i < QUERY_KEYS.length; i += 1) {
|
|
var channel = clean(params.get(QUERY_KEYS[i]));
|
|
if (channel) return channel;
|
|
}
|
|
} catch (e) {}
|
|
return "";
|
|
}
|
|
|
|
function syncTracker(channel) {
|
|
try {
|
|
if (global.tracker && typeof global.tracker.setChannel === "function") {
|
|
global.tracker.setChannel(channel);
|
|
}
|
|
} catch (e) {}
|
|
}
|
|
|
|
function capture() {
|
|
// localStorage 与服务端 cookie 都属于已归因结果,必须先于当前 URL。
|
|
var channel = readStorage() || readCookie() || readQuery();
|
|
if (!channel) return "";
|
|
|
|
writeStorage(channel);
|
|
writeCookie(channel);
|
|
global.__CHANNEL_CODE__ = channel;
|
|
syncTracker(channel);
|
|
return channel;
|
|
}
|
|
|
|
global.ChannelAttribution = {
|
|
get: capture,
|
|
capture: capture,
|
|
};
|
|
|
|
var channel = capture();
|
|
try {
|
|
document.dispatchEvent(
|
|
new CustomEvent("channel:ready", { detail: { channel: channel } })
|
|
);
|
|
} catch (e) {}
|
|
})(window);
|