Nest 短链
- 短链就是 将长链接转换为我自己的短链人为的记个数之类的,方便用户记忆和传播,比如微博的短链,微信的短链等。
流程
注意
利用唯一加密算法 生成压缩码
利用一个随机数 随机生成 0-61 的数字,然后转成字符。 62 的 6 次方,范围有 580 亿 然后生成的时候去数据库查询一下有没有,没有就存入数据库,有就重新生成
将压缩码和长链接存入数据库
利用 302 重定向到长连接
建表
两张表 unique_code表和``short_long_map`表
unique_code 表
id主键code压缩码status状态 0 未使用 1 已使用
ts
model short_long_map {
id Int @id @default(autoincrement())
shortUrl String @db.VarChar(10)
longUrl String @db.VarChar(255)
createTime DateTime @default(now()) @db.Timestamp(0)
}short_long_map 表
id主键shortUrl短链longUrl长链接create_time创建时间
ts
model unique_code {
id Int @id @default(autoincrement())
status Int
code String @unique(map: "unique") @db.VarChar(255)
}使用
安装依赖
bash
npm install base62代码
- 生成短链压缩码
- 存到短链状态表
- 存到短链和长链关联表并且把短链状态置为 1
- 重定向
提供者代码
ts
import { Inject, Injectable } from "@nestjs/common";
import { RedisService } from "../redis/redis.service";
import { ConfigService } from "@nestjs/config";
import { JwtServiceAll } from "../jwt/jwt.service";
// 数据库
import { PrismadbService } from "../prisma/prisma.service";
// 生成短链base62
const base62 = require("base62/lib/ascii");
@Injectable()
export class DuanLianService {
// 注入配置文件
@Inject()
private readonly configService: ConfigService;
// 注入Redis
@Inject()
private readonly redisService: RedisService;
// 注入jwt
@Inject()
private readonly jwtService: JwtServiceAll;
// 注入数据库
@Inject()
private readonly prismadbService: PrismadbService;
// 1. 生成短链压缩码
async setduanliancode(len) {
let str = "";
for (let i = 0; i < len; i++) {
const num = Math.floor(Math.random() * 62);
str += base62.encode(num);
}
return str;
}
// 2. 存到短链状态表
async setduanlian(len) {
// 生成压缩码
const res = await this.setduanliancode(len);
// 查询
const uniqueId = await this.prismadbService.unique_code.findFirst({
where: {
code: res,
},
});
if (uniqueId) {
return this.setduanlian(len);
} else {
const result = await this.prismadbService.unique_code.create({
data: {
code: res,
status: 0, // 0:未使用 1:已使用
},
});
return result.code; // 返回短链
}
}
//3 存到短链和长链关联表并且把短链状态置为1
async setduanlianlong(len, long_link) {
// 存到短链状态表
const result = await this.setduanlian(len);
// 插入
await this.prismadbService.short_long_map.create({
data: {
shortUrl: result,
longUrl: long_link,
},
});
// 更新短链状态表 0 变1
await this.prismadbService.unique_code.update({
where: {
code: result,
},
data: {
status: 1,
},
});
return result;
}
// 4 重定向
async getLongUrl(code) {
const result = await this.prismadbService.short_long_map.findFirst({
where: {
shortUrl: code,
},
});
if (!result) {
return null;
} else {
return result.longUrl;
}
}
}控制器代码
ts
import {
Controller,
Get,
Post,
Body,
Patch,
Param,
Delete,
Query,
Redirect,
Res,
} from "@nestjs/common";
import { UserService } from "./user.service";
import { GlobalCheckException } from "src/common/globalcheck.exception";
@Controller("user")
export class UserController {
constructor(private readonly userService: UserService) {}
// 短链服务
@Get("setduanlian")
async setduanlian(@Query() query: any) {
const result = await this.userService.setduanlianlong(6, query.longUrl);
return {
data: "http://2.jsopy.com:5000/user/" + result, // 你的域名和端口号
};
}
// 增加重定向接口,这里要么返回的是二级域名+压缩码,把二级域名放到白名单。或者自己新建一个路径,放到白名单
// 这样全局拦截器不会拦截
@Get(":code")
@Redirect("./", 302)
async jump(@Param("code") code, @Res() res: Response) {
const longUrl = await this.userService.getLongUrl(code);
return {
url: longUrl,
};
}
}