短链还原 API 怎么接入:展开跳转链路、查看状态码和最终落地页

短链接、二维码链接、推广链接在业务里很常见,但它们也有一个共同问题:用户看到的是短链,开发者和运营同学真正关心的是它最终跳到哪里,中间经过了几跳,每一跳是什么状态码。

unshort 接口就是为这个场景准备的。它可以把一个短链或跳转链接完整展开,返回原始 URL、最终落地 URL、跳转次数、总耗时,以及每一跳的状态码、跳转方式和下一跳地址。对推广短链分析、二维码内容核对、链接巡检、落地页排查来说,这类结构化结果很方便。

这个接口适合做什么

unshort 是一个短链还原 API。它接收一个待展开的 URL,然后追踪跳转链路,最终返回完整的链路明细。

比较适合这些场景:

  • 推广短链落地页核对
  • 二维码背后真实链接检查
  • 站内外链巡检和跳转耗时记录
  • 营销活动上线前确认跳转链路
  • 后台工具里给运营展示"短链最终会去哪里"

它的重点不是单纯告诉你最终 URL,而是把中间每一跳也列出来。比如第一跳是 302 Location,第二跳是最终页面,业务侧就能清楚看到链路是怎么走的。

基本接入信息

接口地址:

text 复制代码
GET https://v1.apizero.cn/api/unshort

请求参数:

参数 类型 必填 说明
url string 要展开的短链或跳转链接,必须以 httphttps 开头
max_hops number 最大跳转次数,范围 1 到 30,默认 10
key string API Key;匿名也可调,登录用户可获得更高额度

最小请求示例:

bash 复制代码
curl --get "https://v1.apizero.cn/api/unshort" \
  --data-urlencode "url=https://httpbin.org/redirect-to?url=https://example.com/landing" \
  --data-urlencode "max_hops=5"

如果要携带 API Key,可以增加:

bash 复制代码
--data-urlencode "key=YOUR_API_KEY"

这里建议用 --data-urlencode,因为被解析的链接本身可能包含 ?&= 等字符,直接拼接 URL 很容易把参数切乱。

2026-05-30 实测返回

我用一个公开跳转地址做了匿名实测:

text 复制代码
https://httpbin.org/redirect-to?url=https://example.com/landing

接口返回如下:

json 复制代码
{
  "code": 0,
  "msg": "成功",
  "data": {
    "original_url": "https://httpbin.org/redirect-to?url=https://example.com/landing",
    "final_url": "https://example.com/landing",
    "hops": 2,
    "total_time_ms": 4234,
    "chain": [
      {
        "hop": 1,
        "url": "https://httpbin.org/redirect-to?url=https://example.com/landing",
        "status": 302,
        "method": "Location",
        "duration_ms": 3480,
        "next": "https://example.com/landing"
      },
      {
        "hop": 2,
        "url": "https://example.com/landing",
        "status": 404,
        "method": "final",
        "duration_ms": 754
      }
    ],
    "is_redirect": true
  },
  "request_id": "mps8wmxu350ae853"
}

这个结果里可以看出几件事:

  1. 原始 URL 是 original_url
  2. 最终落地 URL 是 final_url
  3. 一共经过 2 跳
  4. 第一跳状态码是 302,跳转方式是 Location
  5. 第二跳是最终页,状态码是 404

最后一点也很有价值:短链能展开,并不代表最终页面一定是正常的。业务侧可以根据最终状态码决定是否标记为异常链接。

返回字段怎么看

成功返回后,重点看 data 里的字段:

字段 类型 说明
original_url string 输入的原始链接
final_url string 最终落地链接
hops number 跳转次数,含最终页
total_time_ms number 总耗时,单位毫秒
chain array 每一跳的明细
is_redirect boolean 是否发生重定向

chain 数组里每一项通常包含:

字段 类型 说明
hop number 第几跳
url string 当前跳访问的 URL
status number HTTP 状态码
method string 跳转方式,例如 LocationMeta-Refreshfinal
duration_ms number 当前跳耗时
next string 下一跳 URL,最终页通常没有这个字段

如果要做后台展示,我通常会把结果整理成两层:

javascript 复制代码
const summary = {
  originalUrl: data.data.original_url,
  finalUrl: data.data.final_url,
  hops: data.data.hops,
  totalTimeMs: data.data.total_time_ms,
  isRedirect: data.data.is_redirect,
};

const rows = data.data.chain.map((hop) => ({
  hop: hop.hop,
  url: hop.url,
  status: hop.status,
  method: hop.method,
  durationMs: hop.duration_ms,
  next: hop.next || "",
}));

摘要字段放在顶部卡片,chain 渲染成表格,运营或开发同学扫一眼就能看到链路是否符合预期。

Python 调用示例

后端里可以这样封装:

python 复制代码
import requests


def unshort_url(
    url: str,
    max_hops: int = 10,
    api_key: str | None = None,
) -> dict:
    params = {
        "url": url,
        "max_hops": max_hops,
    }
    if api_key:
        params["key"] = api_key

    resp = requests.get(
        "https://v1.apizero.cn/api/unshort",
        params=params,
        timeout=20,
    )
    resp.raise_for_status()
    result = resp.json()

    if result.get("code") != 0:
        raise RuntimeError(result.get("msg") or result.get("message") or "还原失败")

    return result["data"]


result = unshort_url(
    "https://httpbin.org/redirect-to?url=https://example.com/landing",
    max_hops=5,
)

print("最终地址:", result["final_url"])
print("跳转次数:", result["hops"])

for item in result["chain"]:
    print(item["hop"], item["status"], item["method"], item["url"])

如果是生产环境使用,建议把超时时间、最大跳数和异常处理都放在后端统一封装里。这样前端只需要传入待检测 URL,不直接接触 API Key,也不会因为单个链接解析慢拖住页面。

JavaScript 调用示例

Node.js 18+ 可以这样写:

javascript 复制代码
async function unshortUrl({ url, maxHops = 10, apiKey }) {
  const params = new URLSearchParams({
    url,
    max_hops: String(maxHops),
  });

  if (apiKey) {
    params.set("key", apiKey);
  }

  const res = await fetch(`https://v1.apizero.cn/api/unshort?${params}`);

  if (!res.ok) {
    throw new Error(`HTTP ${res.status}`);
  }

  const data = await res.json();
  if (data.code !== 0) {
    throw new Error(data.msg || data.message || "还原失败");
  }

  return data.data;
}

const result = await unshortUrl({
  url: "https://httpbin.org/redirect-to?url=https://example.com/landing",
  maxHops: 5,
});

console.log("final:", result.final_url);
console.table(result.chain);

如果要接到前端页面,可以把 chain 做成一个跳转链路表:

跳数 状态码 方式 当前 URL 下一跳
1 302 Location 原始短链 落地页
2 404 final 落地页 -

这样比只显示一个最终地址更清楚。

接到业务里的几个小建议

第一,输入前先做 URL 格式校验。官方错误码里说明,url 为空或不以 http/https 开头会返回 4000。前端可以先挡掉明显无效的输入。

第二,合理设置 max_hops。默认 10 已经够大多数短链使用,如果是内部工具,可以允许用户调整,但最好不要直接给到最大值 30。

第三,记录最终状态码。短链展开成功不等于落地页可用,最终跳的 status404500 或超时,都应该在业务侧标出来。

第四,展示每跳耗时。duration_mstotal_time_ms 可以帮助排查到底是哪一跳慢,尤其适合推广链路、活动落地页和二维码跳转排查。

第五,注意使用边界。这个接口适合做自有业务链接核对、公开推广短链分析、二维码内容检查和安全巡检,不适合对无关目标做高频扫描。业务侧要加缓存、频率控制和日志记录。

相关推荐
月落归舟1 小时前
详说缓存四大问题:预热、穿透、雪崩、数据不一致
缓存
蚰蜒螟2 小时前
从mkdir命令到磁盘:Linux内核目录创建过程深度解析
linux·运维·数据库
我是一颗柠檬2 小时前
【Redis】字符串与哈希Day3(2026年)
数据库·redis·后端·database
sakoba2 小时前
MySQL常见问题学习
数据库·学习·mysql
小二·2 小时前
向量数据库深度对比:PGVector vs Qdrant vs Milvus vs Chroma(附性能测试数据)
数据库·wpf·milvus
sleven fung2 小时前
Milvus 向量数据库
开发语言·数据库·python·langchain·milvus
赵渝强老师2 小时前
【赵渝强老师】崖山数据库的数据字典
数据库·oracle
java_cj2 小时前
MySQL 8.0 新特性深度解析:降序索引、Doublewrite Buffer 与 redo log 无锁优化
数据库·mysql
网管NO.12 小时前
多表联查入门|INNER JOIN 内连接,关联查询基础(实操案例)
数据库·sql