/** * 全站渠道首次归因。 * 与落地页约定一致,按 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);