链接缩短 短链接 长链接转为短链接
核心原理
长链接转为短链接的核心原理是: 将短链接与原始长链接做一个映射,访问短链接的时候,通过重定向的方式转到长链接。
应用场景
比如分享功能,查看分享信息的原始链接通常是很长的,直接发给用户,体验不是很好,这时候就可以将其映射为一个短链接再发给用户。
又比如我们熟知的百度网盘分享文件,虽然细节有所差异,但核心原理都是如此。
长短链接映射表结构核心字段设计
字段名 | 字段描述 |
---|---|
code | 短链接代码 |
biz_type | 业务类型 |
biz_no | 业务编号 |
origin_link | 原始链接 |
除了这些核心字段外,还可以根据业务需求设计一些辅助字段。
核心字段说明
code-短链接代码: 用于与短链接域名拼接成短链接的编号,比如code是“123456”,域名是“share.baidu.com”,则完整的短链接为“https://share.baidu.com/123456”;
biz_type-业务类型: 原始链接的内容属于哪个业务,比如分享的是一篇随笔;
biz_no-业务编号: 原始链接的内容所属业务的编号, 比如分享的随笔的随笔编号;
origin_link-原始链接: 访问短链接,会重定向到此原始链接。
实现逻辑
总体步骤
- nginx配置短链接重定向到【Step 2】的接口
- 产品提供根据短链接代码重定向原始链接的接口(根据短链接代码查询原始链接并重定向)
之所以有【Step 1】,是因为短链接代码与原始链接的映射存在数据库中,需要产品提供服务从数据库中根据【code】查询出【origin_link】之后做重定向,而程序提供的查询接口通常包含了一些其它信息(比如接口域名是“server.baidu.com”,而查询接口的uri可能是“/api/share/v1/view/{code}”),仍然不够短。
逻辑
以实际的例子来说明,下面先列举过程中所有需要使用到的素材:
- 短链接代码(code):8lq4Sb
- 短链接域名:share.hulujianyi.com
- 程序接口域名:server.hulujianyi.com
- 程序接口URI以及参数:/hulu-common/api/share/v1/view/?shareCode=$code
- 原始链接(origin_link): https://patient-h5.hulujianyi.com/#/patientDetail?code=8lq4Sb&bizType=2&bizNo=3&t=1693298372310&shareSource=3&shareUserId=7&sign=f4Y9hK0Im23MbzMn%2Fx3st6FgGQO8FAXABSNEuptbXsXxBGj4CbUIpWeY2yGlwMwADBRs9tiYy2Zh
xVkPU7Gjw5CP0zyitnH1GQ48zetfM9XdjYB4MVkowgr1tG2WMCmavggi1Y1Z0KI1GPLASeXOaSQF
IYtOo2gHOhldr%2BGHnc4%3D&e=1694594372310
根据以上信息,则整体逻辑为: - 访问内容的原始链接为【素材5】,而分享到用户的是由【素材1】和【素材2】拼出来的短链接【https://share.hulujianyi.com/8lq4Sb】;
- nginx配置短链接转发到由【素材3】和【素材4】拼出来的程序提供的接口【https://server.hulujianyi.com/hulu-common/api/share/v1/view/?shareCode=8lq4Sb】;
- 接口的功能是根据请求参数shareCode,也即是短链接代码code,从数据库中查询出原始链接,然后做重定向;
- 所以整体流程为:访问短链接 -> nginx重定向到接口 -> 接口重定向到原始链接
根据以上流程,下面贴出一下关键性配置和代码:
- nginx配置转发
# 分享配置
server{
server_name share.hulujianyi.com;
access_log /usr/local/nginx/logs/access.log main;
listen 80;
listen 443 ssl;
include cert.conf; # 这里是引入的ssl的证书配置
location ~ ^/(?<code>[^/]+)/?$ {
return 302 "https://server.hulujianyi.com/hulu-common/api/share/v1/view/?shareCode=$code";
}
}
配置中,正则表达式 ^/(?<code>[^/]+)/?$
捕获 URL 中的URI,在演示例子中截取到的是8lq4Sb
,并将其存储在名为 code
的变量中。然后在配置中使用 code
变量,例如在 rewrite 指令中进行重定向。
2. 接口根据code查询原始链接和重定向的伪代码
@GetMapping(value = "/view")
public void view(@RequestParam("shareCode") String shareCode, HttpServletResponse res) throws IOException {
try {
String link = iShareService.viewLink(shareCode);// 这里是调用的根据code从数据库查询原始链接的方法
res.sendRedirect(link);
} catch (BizException e) {
LOGGER.warn(ExceptionUtil.exceptionStackTraceToString(e));
super.error(res, e);
} catch (Exception e) {
LOGGER.warn(ExceptionUtil.exceptionStackTraceToString(e));
super.error(res, null);
}
}
- 最终访问的原始链接打开的内容,有一些业务校验,则属于另一套体系,这里不做说明。