一条带着十几个追踪参数的营销链接,塞进 70 字的短信正文里几乎必然被截断,这也是短网址存在的原始理由。做活动投放时还遇到过更麻烦的情况:同一条长链在三个渠道分发,事后完全分不清哪个渠道带来了转化,最后只能把长链换成可统计、可过期、可分渠道的短链。短网址生成说到底只有两件事——把长链映射成唯一短码,再让这个短码在访问时重定向回长链。下文按「在线工具 / API 调用 / 自建服务」三条路径给出可照抄的步骤,并单独说明有效期、301 与 302 的选择、防滥用这几处必踩的坑。

短网址生成究竟做了哪两件事
短网址服务只有两个动作:发码和跳转。把这一点想清楚之后,所有方案都只是在这两件事上做不同取舍。
- 发码:为长链生成唯一短码(形如
aY95qu),把「短码 → 长链」的映射关系持久化存储; - 跳转:用户访问短链时,服务端查出长链,返回 302 或 301 状态码加 Location 响应头,由浏览器发起第二次请求。
发码环节常见三种做法。哈希法用 MurmurHash 这类非加密哈希对长链取摘要,再转成 62 进制字符串,速度快但必须处理碰撞,通常的做法是给短码字段加唯一索引,插入冲突就补盐重算。自增 ID 法用发号器(数据库自增、Redis 自增或雪花算法)取一个数字 ID 再 Base62 编码,实现简单且不会碰撞,代价是短码连续、可被顺序遍历。折中做法是在自增 ID 之上再做一次加盐混淆,或者干脆用随机 Token 查表,把 ID 与短码之间的可逆关系切断。
三条实现路径怎么选
选哪条路径,取决于短域名是不是你的资产、以及要不要拿点击数据。三者的差异集中在「谁维护映射表」和「数据归谁」两点上。
| 路径 | 谁维护映射数据 | 适合什么场景 | 主要短板 |
|---|---|---|---|
| 在线工具 | 平台方 | 临时分享、线下物料、活动海报 | 域名不属于你,链接资产沉淀在第三方 |
| API 调用 | 平台方,你只负责调用 | 营销系统批量生成、需要点击统计 | 依赖外部可用性,量起来后产生调用成本 |
| 自建服务 | 你自己的库与缓存 | 品牌短域名、合规内控、长期资产 | 发号、缓存、限流与风控都要自己扛 |
判断顺序其实很直白:一次海报投放用在线工具足够;短链要进 CRM、要按渠道归因,走 API;短域名本身就是品牌资产,或者链接指向内部系统、不允许映射关系出公网,那就只能自建。
自建短链服务的 5 个落地步骤
自建的难点不在生成而在跳转侧的性能与风控,按「发号—建表—加缓存—实现跳转—补风控」五步推进,能少返工。
- 定发号策略:中小规模用数据库自增 ID 加 Base62;分布式部署用号段发号器,由 Redis 批量取号、节点内本地自增;
- 设计映射表:
short_code建唯一索引,除long_url外预留expire_at、channel、password_hash字段; - 加缓存层:把热点的「短码 → 长链」放进 Redis,用布隆过滤器挡住不存在的短码,避免缓存穿透打穿数据库;
- 实现跳转接口:命中缓存直接返回 302,未命中回查数据库并回填缓存;
- 补风控:生成接口按 IP 与 Token 限流,跳转接口单独限流,超限返回 429。
第 1 步的 Base62 转换是整个服务的地基,下面这段 Python 代码把自增 ID 编成短码、再反向解回 ID,可以直接放进项目里使用:
ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
BASE = len(ALPHABET)
def encode(num: int) -> str:
if num == 0:
return ALPHABET[0]
chars = []
while num:
num, rem = divmod(num, BASE)
chars.append(ALPHABET[rem])
return "".join(reversed(chars))
def decode(code: str) -> int:
num = 0
for ch in code:
num = num * BASE + ALPHABET.index(ch)
return num
这段代码解决的是「让 ID 变短」:62 进制下 6 位字符就能覆盖数百亿个 ID,日常业务量完全够用。要注意的是纯自增编码出来的短码是连续的,对外暴露前务必做一次混淆,否则按顺序遍历就能把全站链接爬走。
301 和 302,短链到底该用哪个
短链跳转默认用 302,只有确认长链永不变更时才考虑 301。两者的取舍点在于「还要不要统计」。
| 状态码 | 浏览器行为 | 能否统计点击 | 典型用途 |
|---|---|---|---|
| 301 永久重定向 | 缓存映射关系,后续不再请求短链服务 | 基本不能 | 固定资源、站点永久迁移 |
| 302 临时重定向 | 每次访问都回到短链服务端 | 能,可记录时间、地域、来源 | 营销短链、分渠道归因 |
踩过的坑很典型:某次投放为了压服务器开销改用 301,后台点击数直接掉到真实量的一小部分,原因就是浏览器缓存了映射关系,后续访问根本没经过服务端。凡是需要归因、需要改目标地址的短链,一律用 302。
有效期与防滥用:容易被忽略的两道闸
短链一旦开放生成,就会被拿去跳钓鱼站、被批量刷量、被枚举扫描。上线前把下面四件事做掉,后期能省掉大量救火。
- 设有效期:映射表存
expire_at,跳转前校验,过期返回 410 或落到提示页,不要继续重定向; - 校验目标地址:生成时严格校验协议,只允许 HTTP/HTTPS,把脚本类、data 类等伪协议挡在门外,必要时配可信域名白名单;
- 防枚举:短码长度取 7 位以上并做随机化,监控「连续访问大量不存在短码」的行为,命中后封 IP 或弹验证码;
- 事后复查:定期重扫已生成短链指向的页面,目标站点后期变成恶意内容也要能一键下线。
到这里,短网址生成的完整链路就通了:发号策略决定短码形态,缓存决定跳转性能,状态码决定能不能统计,有效期与风控决定这套服务能安稳跑多久。
常见问题(FAQ)
Q1:短网址生成需要多少钱?
在线工具多数免费;API 按调用量计费;自建主要是服务器与短域名成本,中小规模每月几十元起。
Q2:为什么短链点击数据对不上?
多半用了 301,浏览器缓存映射后不再回源。改成 302 跳转即可恢复统计。
Q3:短码能不能自定义成品牌词?
可以。API 一般支持自定义别名参数,自建时给短码加自定义分支并做重名校验即可。