前端时间在开发 [葡萄城社区] 公众号时有一个功能是需要用网页授权认证地址生成二维码,但类似像下面这样的 Url 即便是看也觉得很头疼了 https://open.weixin.qq.com/connect/oauth2/authorize?appid=xxxxxxxxxxxxxxxxxx&redirect_uri=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&response_type=code&scope=snsapi_base&state=STATE&connect_redirect=1#wechat_redirect
用这个地址生成的二维码也是密密麻麻,虽不影响微信长按扫码,一旦二维码尺寸缩一点点,图片马上就会糊掉,导致摄像头直接扫码会难以识别。
那这种情况下, 我们自然就会想到如果使用短链接减少 url 的字符,生成的码自然就会变得容易识别了,同时还会使 url 更美观且易于转发。现在市面上可用的就是微博的 t.cn 和一些第三方的生成短链接工具,但这两类工具都有一些使用上的问题,例如:t.cn 现在的规则是会出现一个中转页不会直接跳转,而第三方的工具因为是一个公共平台,有时可能会因一些不良信息导致整个平台无法访问。
那与其这样,不如我们自己来实现一个短链接平台吧,实现一个短链接平台原理上也非常简单,搞定两部分就行了:1.保存长短链接的对应关系。2.通过短链接查询长连接并重定向。
为了高效,我这使用的是 node 和 mongodb,下面我们就来开始动手吧。
首先,我们先创建一个 express 工程
express -e demo
change directory: > cd demo install dependencies: > npm install run the app: > SET DEBUG=demo:* & npm start
然后进入 demo 目录并安装 express 必要依赖
npm install
同时通过 npm 安装我们需要用到的 mongoose 和 shortid 和 body-parser
npm install mongoose npm install shortid npm install body-parser
下面分别对使用到的这三个包简单说明一下:
module.exports = { mongo_base_connection_url: 'mongodb://localhost:27017', mongo_db: 'mongodb://localhost:27017/shorturl', mongo_options: { autoReconnect: true, keepAlive: true, reconnectTries: 50, reconnectInterval: 1000, connectTimeoutMS: 5000000, } } console.log("Connection local mongo db");
因为我们的对应关系是需要通过短链接查询长连接,所以这里我们主要以存储短链接和长连接为主,另外大家也可以根据自己需要添加链接点击统计之类的字段,方便后期统计。
var mongoose = require('mongoose'); var Schema = mongoose.Schema;
var urlSchema = new Schema({ shortUrl: String, longUrl: String });
module.exports = mongoose.model('UrlTable', urlSchema);
因为这个应用我们只有生成和 Redirect 两个功能,所以这里只有两个页面即可完成所有工作。
var index = require('./routes/index'); var url = require('./routes/url'); app.use('/', index); app.use('/url', url);
const express = require("express"); const router = express.Router(); const shortId = require('shortid'); const UrlTable = require('../models/urltable'); const mongoose = require('mongoose'); var setup = require('../dbconfig/db');
router.post('/', function(req, res, next) { var params = req.body; var url = params.longUrl; shortId.characters(' 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ^*') var shortid = shortId.generate(); var objurl = { shortUrl: shortid, longUrl: url}; mongoose.connect(setup.mongo_db, setup.mongo_options); UrlTable.create(objurl, function (err, objurl) { //if (err) console.log(err); res.send("http://localhost:3000/" + shortid); }); return; });
指定生成 shortId 字符的范围并生成:
shortId.characters('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')
var shortid = shortId.generate();
为数据库构建符合要求的数据模型:
var objurl = { shortUrl: shortid, longUrl: url};
最后,连接数据库并保存后将短链接结果返回客户端:
mongoose.connect(setup.mongo_db, setup.mongo_options);
UrlTable.create(objurl, function (err, objurl) {
//if (err) console.log(err);
res.send("http://localhost:3000/" + shortid);
});
const express = require("express"); const router = express.Router(); const UrlTable = require('../models/urltable'); const mongoose = require('mongoose'); var setup = require('../dbconfig/db');
router.get('/:shortUrl', function (req, res, next) { var shortUrl = req.params.shortUrl; mongoose.connect(setup.mongo_db, setup.mongo_options); UrlTable.findOne({ shortUrl:shortUrl }).then((result) => { //待添加错误处理 res.redirect(result.longUrl); }) });
module.exports = router;
这个页面为了便于快速跳转,我们就使用 get 接收参数,这个页面功能就很简单了,接参查询并跳转。
接收短链接码
var shortUrl = req.params.shortUrl;
连接数据库查询并跳转
mongoose.connect(setup.mongo_db, setup.mongo_options);
UrlTable.findOne({ shortUrl:shortUrl }).then((result) => {
//待添加错误处理
res.redirect(result.longUrl);
})
后期大家可以对一些错误异常处理,数据统计等做一些增强,这里就不做补充了。
下面让我们启用应用开始测试吧。
npm start
启动后,默认的访问端口为 3000,我们首先测试下短链接生成页,这里我们 post 一个名为 longUrl 的长链接参数,数据对象为:
{"longUrl" : "https://demo.grapecity.com.cn/spreadjs/SpreadJSTutorial/features/tables/basic-table/purejs"}
成功升成了如下短链接:
http://localhost:3000/iGE6ZlDmh
我们只要通过访问短链接能正常跳转至保存的长连接即可。
这样就测试通过了,其实代码量不大,原理也很简单。大家如果自己有较短的域名的话,上线后会让链接变得更短、更美观,这样一个属于我们自己短链接生成平台就开发完成了。下面附上源码,执行 npm install 即可自动安装所有依赖,如果大家有问题,可通过评论区告诉我。
1
opengps 2020-09-25 09:36:54 +08:00 via Android
首先得有一个短域名,我找了好几年只看好一个中意的(4 位 cn),已在个人网站下用了 3 年
|
3
easonHHH 2020-09-25 09:42:11 +08:00
直接拷贝代码是真的没有看下来的欲望,建议代码块格式一下
|
5
yamedie 2020-09-25 09:48:20 +08:00
貌似是 KPI 帖
有个疑问: router.get('/:shortUrl', function (req, res, next) { var shortUrl = req.params.shortUrl; mongoose.connect(setup.mongo_db, setup.mongo_options); UrlTable.findOne({ shortUrl:shortUrl }).then((result) => { //待添加错误处理 res.redirect(result.longUrl); }) }); 楼主这样写, 每个短链接的 get 请求发来, 都现连接数据库, 效率也太低了吧? 而且连接数据库是异步的, 需要回调函数或者 async/await 执行后面的语句, 这里直接写成同步写法了, 让我有点摸不着头脑 😨 |
6
zpfhbyx 2020-09-25 09:50:35 +08:00
yourls 不香么。。
|
7
shc 2020-09-25 09:51:17 +08:00 via Android
|
8
GrapeCityChina OP @yamedie 你的建议很好,你这样会使效率更高,这也是一个可优化的点
|
10
linstrong 2020-09-25 10:26:25 +08:00
之前在网上找了一个 MyURL 的短网址程序,傻瓜式安装,唯一的缺点就是没有后台,用了一个两位的.cm 域名搭建了一个,感觉还行
|
11
heheda0 2020-09-25 10:56:57 +08:00
之前用 go 做了一个 http://url.2048ai.cn/short_url
|
13
zhuweiyou 2020-09-25 11:49:24 +08:00
缺的是程序吗?
我缺的是短域名 |
14
JavaIO 2020-09-25 12:06:48 +08:00
有个短域名不容易
|
15
coloz 2020-09-25 15:03:40 +08:00
短链接平台有啥商业模式不。有个 3 位短域名
|
16
Livid MOD @memedahui 谢谢举报。这个主题已经被移动到 /go/promotions 并被下沉。
|
17
tercel36524 329 天前
https://www.369url.cn/ 这个可以的
|