杂记 › 技术笔记 › 投放链接的装配顺序与大小写折叠:UTM 生成器六态标注、两道硬上限与五栏各用一把尺实测

投放链接的装配顺序与大小写折叠:UTM 生成器六态标注、两道硬上限与五栏各用一把尺实测

原链 UTM_SOURCE=a 配表单填 b 只出一份小写键;六态标注、keep 开关的两行差分、五栏各用一把尺、8 条与 30 行两道硬上限,逐笔实测。

同一条链接里明明有 utm_source,生成出来会变两个吗

开测前最好奇的是:原链写 UTM_SOURCE=a 全大写,表单 source 填 b,产物里是两组 utm_source 并存还是一组。第二个疑问来自面板:五个格子都填满了,「参数条数」那一栏却给了 6。跑完一轮纯 Node 才确认,这是两套账:前者是认领环节折了大小写,后者是那五个数各用一把尺。

被测的是UTM 链接生成器这一页,模板实测 30156 字节、正文 620 行。UB 状态对象直接构造,DOM 只走到 ubEl 返回 null 为止,渲染后的表格行数、按钮态、复制反馈一律标未实测;下面的数字全是字符串层实测,长度口径是 UTF-16 码元。

折叠发生在认领那一步

ubAssemble(L277-320)拿原链拆出的每一对键值去撞表单要写入的条目,撞的条件是两边都先转小写再比。实测原链 UTM_SOURCE=a 配 source 填 b,产物 query 只剩 utm_source=b,res 里等号 1 个——键名按 UB_FIELDS 的规范小写输出,大写那枚没被留下,也不存在并存的两组。更挤的样本是同一条链放两枚只差大小写的同键:UTM_source=old 与 utm_source=older,第一条被认领判覆盖原值,第二条走已清除,表格三行依次是覆盖原值、已清除、覆盖原值。

六个状态,两套计数

每个参数最后只落六种 st 之一。第六种是表单值撞上一枚已用过的小写键:source 填 b 再挂一条自定义 utm_source=x,第二次判「重复已忽略」,产物只有一份 utm_source。

状态触发条件
覆盖原值原链键折小写命中表单值,且它还没被用过
已清除原链是 utm、保留没勾、又没被认领
沿用原值非 utm 键,或勾了保留却没被认领的 utm
新增/新增自定义表单值没被置位,小写键也没被用过
重复已忽略表单值没置位,但那枚小写键已用过

检查区的两个计数与状态并不通约:dropped 只数「已清除」的行,kept 只数「沿用原值」且命中 /^utm_/i 的行,沿用的非 utm 行两边都不进。

keep 开关只改旧值的去向

取一条自带三枚 utm 的原链,表单只填 source:不勾保留时 query 14 码元、cnt 1、dropped 2,另两行判已清除;勾上保留时 query 48 码元、cnt 3、kept 2,同样那两行改判沿用原值。两边表格行数恒 3,差的只是最终串。

原链三枚旧 utm × 表单只填 source 不勾保留 勾上保留 utm_source 覆盖原值 覆盖原值 utm_medium 已清除 沿用原值 utm_campaign 已清除 沿用原值 query 14 / cnt 1 / dropped 2 query 48 / cnt 3 / kept 2 两边表格行数恒 3。

图 1:keep 两档下三枚参数的落点与差分。

五栏各用一把尺

面板五栏依次是整条 url、base、query 的码元数,query 按 & 切开的段数(空 query 给 0),以及表格行里命中 /^utm_/i 的行数,含被清除的行。

分歧样本:原链带 3 枚旧 utm 外加一枚非 utm 的 id=7,表单填满 5 格,不勾保留。实测 total 97、base 25、query 71、cnt 6、utm 5。按「拼了五个 utm」的直觉期望 5,cnt 却给 6,多出的一段正是被沿用的 id;把 id 摘掉的另一组里 base 25 加问号加 query 67 得 93,与 total 逐条相等。

同一次装配的五栏读数 total 97 整条 url base 25 问号前那一段 query 71 等号与 & 都算 cnt 6 按 & 切段,含 id utm 5 只数 utm_ 前缀行 25 + 1 + 71 = 97;cnt 6 与 utm 5 差一枚 id。

图 2:五栏各自的尺,与 cnt 和 utm 的分歧点。

值留空走的是两条路

自定义值留空时,产物是 ?gdt_vid 这种带键不带等号的标记位;标准五格里填空格却被整格跳过——source 填三个空格时 query 只剩 utm_medium=email,链接 42 字符。

解码先换加号

ubDecode(L238-241)先把加号整体换成空格,再交给 decodeURIComponent,抛 URIError 就原样回显。实测 %2B 解成一枚加号、单独的 + 解成空格、%ZZ 原样回显成 3 码元、%E4%B8AD 因第三段是裸 AD 回显成 8 码元,而写法正确的 %E4%B8%AD 解回一枚中文。同一段 %xx 串的正反两向,URL 编解码那一页单独处理。

两道硬上限不在同一个函数里

UB_MAX_CUSTOM 实测 8,落点两处:添加自定义在长度已到 8 时先给提示再退回,custom 维持 8 条;拆解链上参数超过 8 时走截断——10 枚非 utm 加一枚 utm_term 的样本得 other 10、dropped 2、custom 留到 8。UB_MAX_VARIANTS 实测 30,在 ubVarLines(L434-445)里先去重再判长:31 行唯一值得 lines 30、over 1,40 行时 over 10,产物恒取前 30 条。去重大小写敏感,Banner 与 banner 算两条;真·空行既不记重复也不记空值,只有空格或制表符组成的行才计 blank。

预设的 label 与值是两回事

UB_PRESETS 实测 18 条,label 与 source、medium 两列互不相等:「微信公众号」配 weixin 加 social,「百度自然」与「百度竞价」同为 baidu,只差 organic 与 cpc。高亮判据要求 source 与 medium 同时相等,只改 baidu 不点亮。UB_MEDIUMS 实测 13 档,只动 medium。这些名字在本页只是字符串事实。

文案与代码差在三处

页面配置里本工具的 18 条说法逐条对实测行为判,结果 [一致] 15、[部分一致] 3、[冲突] 0:状态标注只列了五种,代码里 st 有六种;campaign 留空给的是提示档,medium 留空才是注意档;付费渠道白名单文案列 5 档,代码正则实含 6 档。那五个键各自的含义与大小写为什么把报表拆成两行,站内旧文讲过,不复述。

常见问题

Q:原链上的大写键名会被保留吗?

被认领的那条不会,它按表单侧的规范小写重拼,也不与新值并存;只有走沿用原值的行保留原样。

Q:参数条数为什么比 utm 条数多一?

参数条数按 & 切段,沿用的非 utm 参数也算一段;utm 条数只数表里命中 utm_ 前缀的行,连被清除的行都算。

Q:变体超过 30 行是硬截断还是只给提示?

先去重再截,产物只有前 30 条,尾注写出被截掉的行数,40 行唯一值时 over 记 10。

📎 相关文章

8 个元素算得出 40320 条却只列 5000 行:排列计算器的两道互不相干的上限、重复元素按 3! 计数与 n≤20 的过程断点 2026-11-12 13格算法表与7道验签闸门:JWT 工具页验签侧的分支比解码侧更窄,逐算法真签真验矩阵 2026-11-12 拖到 4 和拖到 8,屏幕上都是 43890 个块:马赛克预览与导出的两套块网格、三档会崩与 6px 误触阈值 2026-11-10 位图进 SVG 只换了个盒子:232 字节容器常数、一个从不生效的「base64 嵌入」勾选,与四档缩放下纹丝不动的 142064 个字符 2026-11-10 转完悄悄少了 271 个字符:Markdown 转 HTML 的洞协议、64 轮回填与 20 条提示上限 2026-11-10