一、 开发背景
业务对外推广,由于我们的推广地址需要拼接上渠道码和来源,以区别和统计该渠道下用户数据,但下发到用户手机上的地址太长,希望对外暴露的地址越短越好,所以需要将我们的推广地址缩短,就例如我们接收到的手机推广短信中的短链接类似。
二、 实现方案
- 第一种方案:通过运维nginx代理配置,nginx无法配置带参数的url,无法满足业务需求。
- 第二种方案:Java后端实现,但后端排期非常靠后,业务需求紧急。
- 第三种方案:通过前端NodeJS+MongoDB实现,前前后后花了一个小时。最终选择该方案。
三、实现思路
第一步:新建short-url目录,进入该目录下,安装express,mongoose,ejs,shortid依赖包,需要说明的是shortid,生成唯一的短链接id标识,参考:www.npmjs.com/package/sho…
mkdir short-url
cd short-url
npm init -y
npm i express mongoose ejs shortid
npm i --save-dev nodemon
修改package.json:
"scripts":
{
"dev": "NODE_ENV=development nodemon server.js"
}
项目启动命令:npm run dev
第二步:建立数据模型,新建目录文件,models/shortUrl.js
const mongoose = require('mongoose');
const shortUrlSchema = new mongoose.Schema({
full: {
type: String,
required: true
},
short: {
type: String,
required: true
},
clicks: {
type: Number,
required: true,
default: 0
}
})
module.exports = mongoose.model('shortUrls', shortUrlSchema)
第三步:新建index.js:
const express = require('express');
const mongoose = require('mongoose');
const shortid = require('shortid'); // shortid创建唯一的短标识符
const ShortUrls = require('./models/shortUrl');
const app = express();
// 连接数据库
const MONGO_URL = 'mongodb://localhost:27017/urlShortener';
mongoose.connect(MONGO_URL, { useNewUrlParser: true, useUnifiedTopology: true });
// 使用ejs渲染引擎
app.set('view engine', 'ejs');
app.use(express.urlencoded({extended: false}))
// get获取短地址和长地址列表
app.get('/', async (req, res) => {
const shorUrls = await ShortUrls.find();
res.render('index', { shorUrls });
});
// 生成长链接与短链接
app.post('/shortUrls', async (req, res) => {
const full = req.body.fullUrl;
const short = PATH_URL+shortid.generate();
if (!full) return res.json({msg: '查询出错,请返回重试!', code: '1021'});
const hadFullUrl = await ShortUrls.find({ full });
/* 如果已存在不再创建 */
if (hadFullUrl.length !== 0 ) {
return res.json({msg: '已存在,请不要重复生成!', code: '1022'});
}
await ShortUrls.create({ full: req.body.fullUrl, short: short });
// 生成成功后刷新页面
res.redirect('/');
});
// 访问短地址重定向到长地址
app.get('/:shortUrl', async (req, res) => {
const shortUrl = await ShortUrls.findOne({ short: req.params.shortUrl });
if (shortUrl == null ) return res.sendStatus(404)
shortUrl.clicks++; // 记录点击打开次数
shortUrl.save(); // 保存到数据库
res.redirect(shortUrl.full); // 访问短链时redirect到长链上
});
app.listen(process.env.PORT || 5001);
第四步:
实现思路
http://localhost:5000/ihjmCKJ3H
get请求识别到短链标识 ihjmCKJ3H,到数据库查对应的长链接,
重定向到长链接上
res.redirect(shortUrl.full); // 访问短链时redirect到长链上
项目调试,修改优化。
至此,基于NodeJS+MongoDB的URL链接缩短服务完美实现。
另外,如果服务器部署和mongodb配置如果有不会有同学可以联系我,我们一起交流进步成长。