深入短链还原API:从请求参数到工程落地的完整指南
适用场景:谁需要追踪短链的每一跳?
短链(如 t.cn、bit.ly 等)在日常分享、营销中广泛使用,但隐藏了实际目标地址。安全分析人员需要还原完整跳转链以核查是否存在钓鱼重定向;运营人员需要分析短链的落地页是否正常;开发者在对接第三方服务时也经常需要验证短链的最终地址。本 API 的核心能力是逐跳还原,输出每一跳的状态码、跳转方式(HTTP Location 或 HTML Meta-Refresh)以及耗时,相当于给每次短链访问做一次“慢镜头回放”。
接口能力边界
- 请求方法:GET
- 端点:
https://v1.apizero.cn/api/unshort - QPS 限制:5 次/秒(超过限制会返回 429)
- 最大可追踪跳数:通过
max_hops参数控制,范围 1~30,默认 10。如果短链实际跳数超过此值,API 只返回前 N 跳,并在最后一跳的状态码上标识截断。 - 支持的跳转方式:HTTP 301/302/303/307/308 以及 HTML
meta标签http-equiv="refresh"的跳转。对于 JavaScript 跳转(如 window.location)无法直接追踪。 - 适用短链类型:绝大多数公开短链服务生成的链接,包括但不限于 t.cn、url.cn、dwz.cn、bit.ly、tinyurl.com 等。
请求参数与鉴权
| 参数名 | 必填 | 类型 | 说明 | 默认值 | 示例值 |
|---|---|---|---|---|---|
| url | 是 | string | 要展开的原始短链(需 URL 编码) | 无 | https%3A%2F%2Ft.cn%2FA6xxxx |
| max_hops | 否 | number | 最大追踪跳数,1~30 | 10 | 5 |
鉴权方式
API 使用X-API-Key请求头传递密钥。开发者需先在平台申请 API Key,并在每次请求时携带。示例:
X-API-Key: your_api_key_here注意:请求头大小写敏感,标准名称为X-API-Key(首字母大写、连字符分隔)。
curl 接入示例(可复制)
以下示例使用环境变量$APIZERO_API_KEY存储 API Key,可直接在终端运行。请先设置export APIZERO_API_KEY=你的密钥。
基础请求(默认 10 跳)
curl -sS -X GET \ -H "X-API-Key: $APIZERO_API_KEY" \ "https://v1.apizero.cn/api/unshort?url=https://t.cn/A6xxxx"指定最大跳数(例如 5 跳)
curl -sS -X GET \ -H "X-API-Key: $APIZERO_API_KEY" \ "https://v1.apizero.cn/api/unshort?url=https://t.cn/A6xxxx&max_hops=5"使用 jq 美化输出
curl -sS -X GET \ -H "X-API-Key: $APIZERO_API_KEY" \ "https://v1.apizero.cn/api/unshort?url=https://t.cn/A6xxxx" | jq .注:上述示例中的短链
https://t.cn/A6xxxx仅为占位,请替换为实际短链。
返回值深度解读
成功响应 HTTP 200,Body 为 JSON 对象,最外层包含code、msg、data。
顶层结构
{ "code": 0, "msg": "成功", "data": { "original_url": "https://t.cn/Aabc", "final_url": "https://example.com/landing", "hops": 2, "is_redirect": true, "total_time_ms": 412, "chain": [ { "hop": 1, "url": "https://t.cn/Aabc", "status": 302, "method": "Location", "next": "https://example.com/landing", "duration_ms": 120 }, { "hop": 2, "url": "https://example.com/landing", "status": 200, "method": "final", "duration_ms": 292 } ] } }字段说明
| 字段 | 类型 | 描述 |
|---|---|---|
original_url | string | 传入的原始短链 URL |
final_url | string | 最终到达的 URL,若无重定向则与 original_url 相同 |
hops | number | 实际追踪到的跳转次数(不含最终页) |
is_redirect | boolean | 是否有过重定向(与原始 URL 不同) |
total_time_ms | number | 所有跳转累计耗时(毫秒),注意这是服务器端请求各跳的总耗时,并非客户端实际浏览时间 |
chain | array | 跳转链数组,按hop升序排列 |
chain 元素字段:
| 字段 | 类型 | 描述 |
|---|---|---|
hop | number | 跳序号,从 1 开始 |
url | string | 当前跳请求的 URL |
status | number | 当前跳返回的 HTTP 状态码(若为final跳,则为最终页状态码) |
method | string | 跳转方式:"Location"表示通过 HTTP Location 头重定向;"Meta-Refresh"表示通过 HTML meta 刷新跳转;"final"表示追踪结束,无后续跳转 |
next | string | (仅非 final 跳)下一跳的目标 URL |
duration_ms | number | 从发起当前跳请求到收到响应的时间(毫秒) |
关键要点:当
method为final时,next字段不存在;status可能为 200(正常)或 404/403 等表示最终页状态。若短链实际跳数超过max_hops,最后一跳的method仍为final,但status中会附带错误标识(如 499 表示截断)。
常见错误与处理建议
| HTTP 状态码 | 返回 code | 可能原因 | 处理方式 |
|---|---|---|---|
| 200 | 0 | 成功 | 正常解析 data |
| 200 | 1001 | 参数错误(如 url 为空或格式非法) | 检查 url 是否 URL 编码 |
| 200 | 1002 | 认证失败(API Key 无效或未携带) | 检查X-API-Key请求头 |
| 200 | 1003 | 短链解析超时(可能目标服务器响应过慢) | 可重试,或检查网络连通性 |
| 200 | 1004 | 跳数超过限制(max_hops 超 30 或实际跳数过量) | 适当增加 max_hops(最大 30) |
| 429 | – | 请求频率超限 | 降低并发,遵守 5 QPS 限制 |
| 5xx | – | 服务端内部错误 | 等待后重试,若持续则反馈平台 |
特别的「截断」场景:当 real hops > max_hops 时,API 仍返回 200,但chain最后一跳的method为final,status为499(自定义标识),同时duration_ms只累计到截断处。此时final_url为最后一次成功响应的 URL,但可能并非最终落地页。
工程化注意事项
1. 请求频率控制
QPS 为 5,意味着单个 API Key 每秒最多发起 5 次请求。在批量处理短链时(例如分析 1000 条短链),建议采用令牌桶或固定窗口限速,将请求间隔控制在 200ms 以上。一个简单的 Go 实现思路:
import "time" func rateLimitedRequest(url string, apiKey string) { // 使用 time.Ticker 控制每秒 5 次 ticker := time.NewTicker(time.Second / 5) for _, url := range urls { <-ticker.C go sendRequest(url, apiKey) } }2. URL 编码与拼接
传入的url参数必须做 URL 编码。例如短链本身含问号、井号时,需整体编码。可使用encodeURIComponent(JavaScript)或urllib.parse.quote(Python)处理。
推荐使用查询字符串构建库或框架自动处理,避免手动拼接。
3. 超时与重试策略
API 本身有超时限制(约 15s,以具体文档为准)。建议客户端设置更严格的超时时间(如 10s)。对于返回1003或网络错误,可采用指数退避重试(最多 3 次)。
4. 结果缓存
同一短链在短时间内(例如 5 分钟内)的跳转链通常不会变化。可在应用层缓存final_url及chain,减少重复请求。缓存 key 可用url + max_hops拼接的哈希值。注意缓存的 TTL 不宜过长,因为某些短链支持自定义跳转目标。
5. 对 Meta-Refresh 的特殊处理
如果 API 返回method: "Meta-Refresh",说明目标页面通过<meta http-equiv="refresh" content="0;url=...">跳转。这种跳转需要客户端解析 HTML,但本 API 已自动识别。开发者只需关注next字段即可。
6. 错误码与日志
生产环境中建议记录每次请求的原始返回(包括 HTTP 状态码和 code),便于异常分析。对于code != 0或 HTTP 非 200 的情况,统一打 warn 日志并关联请求参数。
7. 使用场景限制
- 本接口不适用于追踪要求客户端执行 JavaScript 的重定向。
- 某些短链服务可能对机器人访问有限制(如 Cloudflare 防护),此时 API 可能返回 403 或超时。
- 追踪耗时
total_time_ms受网络波动影响,单个结果不具备高精度,但统计多组数据后可用作趋势参考。
实战技巧:如何用 Python 批量还原
以下是一个简单的 Python 脚本示例(假设已安装requests):
import requests import time API_URL = "https://v1.apizero.cn/api/unshort" API_KEY = "your_api_key_here" def unshort(url, max_hops=5): headers = {"X-API-Key": API_KEY} params = {"url": url, "max_hops": max_hops} resp = requests.get(API_URL, headers=headers, params=params, timeout=10) data = resp.json() if data.get("code") == 0: return data["data"] else: raise Exception(f"Error {data['code']}: {data['msg']}") # 示例用法 short_urls = ["https://t.cn/A6xxxx", "https://bit.ly/3abcde"] for su in short_urls: try: result = unshort(su, max_hops=10) print(f"{su} -> {result['final_url']} (hops: {result['hops']})") time.sleep(0.3) # 限速 except Exception as e: print(f"Failed: {su}, error: {e}")- 需要注意 API Key 不要硬编码在代码仓库中,建议通过环境变量或配置中心注入。
- 限速间隔 200ms 可安全运行在 QPS 5 下。
参考文档
- 短链还原 API 文档
- 原始 Markdown 文档
本文所有示例均基于上述文档提供的真实接口地址与参数编写,开发者若遇到与文档不一致之处,请以官方文档为准。
