在短链接后面直接再接一串参数,是分享时很常见的做法。例如有人已经拿到一条短地址,再在末尾补上 utm_source 之类的标记,就默认目标页或统计系统已经收到。这里容易把两件事当成一件事:你在分享用的那一行字后面写了参数,和用户到达目标页时,地址里是否还带着这些参数。前者只说明眼前这串字符被改过,不能直接证明后者已经发生。
本文要说清楚的是网址结构本身:问号、& 和 # 各管哪一段;参数是写在短地址这一层,还是写在目标地址里;以及为什么把参数直接拼在短链接后面,并不等于目标页已经收到。验证时应看跳转结束后的完整地址。文中例子一律使用 example.com 示意,不是可访问的真实活动链接,也不能据此推断趣码会对追加参数做透传或保留。

一份网址并不只是“前面是域名、后面随便接字”。IETF 于 2005 年 1 月发布的 RFC 3986《URI Generic Syntax》把通用 URI 写成:scheme、层次部分,然后可以跟查询部分,再可以跟片段标识。查询部分由第一个问号 ? 开始,到井号 # 或该 URI 结束为止;片段标识由 # 开始,一直到该 URI 结束。
查询部分里具体写成什么,规范把格式交给资源自己定义。实践中,很多页面用“名称=值”的成对写法来携带参数。Mozilla 开发者网络(MDN)的 URI 查询说明里,用 http://www.example.com:80/path/to/myfile.html?key1=value1&key2=value2#SomewhereInTheDocument 作为示意:问号后面的 key1=value1&key2=value2 是查询部分,成对项目之间用 & 分开。Google Analytics 帮助中心的《网址构建工具:使用自定义网址收集广告系列数据》在讲解手动添加 UTM 参数时,也写得很明确:用问号把参数与网址隔开,参数和值以等号成对列出,每一对之间用和号 & 分开,例如 https://www.example.com/?utm_source=email_campaign&utm_medium=email&utm_campaign=summer-sale。该页还指出:向网址中添加参数时,一定要使用 utm_source、utm_medium 和 utm_campaign;参数值区分大小写。这些要求针对的是把标记写进目标网址本身,并不能外推成“任意短链工具都会转发你后来补上的字符”。
一个容易忽略的细节是:如果目标地址里已经有问号,再追加参数时通常应使用 & 接在已有查询后面,而不是再写第二个问号。第二个问号并不自动开启“另一段查询”,它可能被当成查询内容里的普通字符,结果和设想不一致。反过来,如果地址里还没有问号,第一组参数才用 ? 开头。验证时看的是跳转结束后的完整地址,而不是只看自己刚刚敲进去的那一行。
# 后面是片段标识,不是查询参数的另一种写法。MDN 对 URI 片段的说明是:它用于标识资源中的某一部分,例如文档中的一节;“在请求该 URI 时,片段不会被发送到服务器,而是由客户端(例如浏览器)在获取资源之后再处理”。RFC 3986 第 3.5 节也把片段标识定位为客户端侧的间接引用:它指向主资源之上的次级资源,语义由取回的表示(例如某种媒体类型)来定义,而不是由服务器在这次请求里单独接收。
因此,下面两种写法看起来都“带了参数”,含义并不相同。示意:
https://example.com/page?utm_source=newsletter&utm_medium=email#signup
这里的 UTM 仍在查询部分,#signup 才是片段。
https://example.com/page#signup?utm_source=newsletter&utm_medium=email
这里从 # 开始直到结尾都属于片段。按上述规范与 MDN 的说明,请求服务器时通常不会带上这一段;页面也许仍会滚到某个锚点,但不能据此认为统计系统或目标页的服务端逻辑已经收到了 utm_source。如果目标页本身要用片段来定位某一屏,正确的顺序一般是:先写完查询参数,再把 # 和片段放在整段地址的最后。
这一点与“短链接会不会转发参数”是两层问题。就算后面要讨论跳转是否带上查询部分,先写错位置,把本该放在问号后面的标记写进了井号后面,验证时也应先把这一层错误排除掉。
短链接常见的使用方式,是先准备好目标地址,再生成一条更短的入口地址。用户点击短地址后,经由重定向等方式到达目标页。由此至少出现两层地址:分享时被人点击的短地址,以及跳转结束后浏览器里出现的目标地址。参数写在哪一层,含义并不自动相同。
第一种做法,是在生成短链接之前,就把需要的参数写进目标地址。示意:目标为 https://example.com/landing?utm_source=newsletter&utm_medium=email,再为这条完整目标地址生成短入口。这时,参数属于目标地址的一部分。是否仍能在跳转后的地址栏里看到它们,要以实际打开后的完整地址为准,但这至少是把标记放在了“目标页这一层”。
第二种做法,是短链接已经生成之后,再在短地址后面追加字符,例如写成 https://example.com/s/demo?utm_source=newsletter(/s/demo 仅为示意路径)。这时,这些字符首先属于短地址这一层。短链服务随后如何处理它们——是忽略,是附加到目标地址,是与目标地址里已有的查询合并,还是走别的规则——取决于具体实现,不能从“我已经拼上了”反推“目标页一定收到了”。不能仅凭 URI 句法判断趣码或其他短链服务的具体参数处理方式;是否保留、合并或改写,应以相应服务现行说明和实际跳转测试为准。
还要注意:给短地址追加查询,和给目标地址追加查询,即使字符看起来差不多,经过跳转后也可能对不上。短链点击次数、自己复制时看到的那一行,都还不是目标页已经收到参数的证据。不能把入口点击数直接当成目标页或外部统计工具已经按 UTM 记上一笔。
要判断参数有没有到达目标页,最直接的办法不是反复检查自己有没有把字拼对,而是用即将对外发布的那一整串地址,完成一次实际打开,并阅读跳转结束后的完整地址。
可以按下面的顺序核对:
先确认参数写在哪一层:是生成短链接之前就已经写在目标地址里,还是后来追加在短地址后面。再用即将发布的完整字符串打开,而不是只用生成时的短地址、或只用记忆中的目标地址。等待跳转结束,不要停在中间提示页(如果出现的话)。然后复制地址栏里的全文,而不只看浏览器或许折叠过的显示。核对查询部分是否出现在第一个 ? 之后、第一个 # 之前,名称和值是否与预期一致,大小写是否被改写,是否误用了第二个问号,是否把标记写进了片段。
如果最终地址里没有这些查询,或名称值对不上,结论只应是:在这次打开中,目标页地址没有呈现出你预期的参数。不要立刻写成“短链工具一定会丢参数”或“统计系统坏了”。先回到书写位置和 ?、&、# 的顺序,再决定是否需要调整目标地址后重新生成,或改用其他已核实的标记方式。若还要看统计报表,应在最终地址已经带上预期查询之后,再去对照相应工具是否识别这些标记;报表里没有数据,也不能单独证明是短链接这一层出了问题。
不同浏览器、应用内置网页和系统,对地址显示、跳转和片段处理的表现可能不同。自己已登录的电脑上成功一次,不能代表所有用户都会得到同一条最终地址。无法覆盖的环境应如实记下,不要把未测试的结果写进对外说明。若打开后根本到不了目标页,应先分清是跳转异常、登录页还是目标已失效,再回头核对这些参数。
参数本身仍须遵守基本边界:不要把手机号、令牌等敏感信息放进对外分享的地址。缩短入口并不能加密目标地址里已经存在的内容。
先分清问号、& 和 # 各管哪一段,再分清参数是写在目标地址里还是追加在短地址后面,最后以跳转结束后的完整地址做验证。这样,至少不会把“我已经把参数拼上去了”误当成“目标页已经收到了”。