短链接还原本质是“解码+内部重写+透传处理”,需借助外部服务或预定义规则;nginx不存映射,常用rewrite静态映射、lua+redis动态查表或网关服务协同实现,须避免暴露长链和无限循环。

短链接还原为长链接并转发,本质是“解码 + 内部重写 + 透传处理”,不是简单跳转。Nginx 本身不存储短链映射关系,所以必须配合外部服务(如 Redis、数据库)或预定义规则来完成还原。关键在于:还原动作发生在 Nginx 内部,浏览器地址栏不变;转发由 proxy_pass 或后端应用实际承接。
用 rewrite 指令做静态映射还原
适用于短链数量少、规律明确的场景(例如所有短链形如 /s/abc123,且已知 abc123 → /api/v2/order?uid=789&tid=456):
- 在
location块中用正则捕获短链 ID,查表或硬编码映射到长路径 - 使用
rewrite ... break;防止循环,确保只重写一次、不触发新 location 匹配 - 后续由
proxy_pass或fastcgi_pass将重写后的 URI 转发给真实处理器
示例配置:
location ^~ /s/ {# 将 /s/abc123 → /api/v2/order?uid=789&tid=456
rewrite ^/s/(abc123)$ /api/v2/order?uid=789&tid=456 break;
rewrite ^/s/(def456)$ /api/v2/user/profile?id=1001 break;
proxy_pass http://backend;
}
用 Lua 脚本实现动态查表还原(OpenResty)
更实用的方案:Nginx + OpenResty + Redis。短链 ID 作为 key 查询 Redis 获取原始 URL 或参数,再构造完整请求:
- 在
access_by_lua_block中读取$uri,提取短链码 - 调用
redis:get("short:" .. short_id)获取目标路径(如/order/create?item=book&qty=2) - 用
ngx.req.set_uri(..., true)替换当前 URI 并保留原始 query 参数 - 后续直接
proxy_pass到上游,无需 rewrite 指令
优势:映射可热更新、支持海量短链、不重启 Nginx。
用 return + 后端服务协同还原(推荐轻量级部署)
如果不想引入 Lua 或复杂模块,可让短链请求先到达一个轻量网关接口(如 Python Flask / Node.js),由它完成查库、还原、返回 307 或 200 响应:
- Nginx 配置仅做路由分发:
location ^~ /s/ { proxy_pass http://gateway-service; } - 网关服务接收
/s/xyz,查出原始目标,返回307 Temporary Redirect到长链接(保持 method 和 body) - 或直接代理转发(
proxy_pass http://upstream$target_path),由网关拼接完整 URI
这种方式逻辑清晰、调试方便,适合中小规模业务快速上线。
注意事项与避坑点
避免常见错误:
- 不要用
permanent或redirect标志——那会暴露长链接,失去“短链”意义 - 慎用
last:可能引发 location 重复匹配和无限循环(Nginx 限制最多 10 次) - query 参数含特殊字符(如
&,=,/)时,需在 rewrite 中用\?转义问号,或改用$args显式拼接 - 若后端是 PHP-FPM,注意
fastcgi_param SCRIPT_FILENAME需随 URI 变化同步更新,否则仍执行旧脚本











