三步带你开发一个短链接生成平台 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
GrapeCityChina
V2EX    推广

三步带你开发一个短链接生成平台

  •  
  •   GrapeCityChina 2020-09-25 09:31:08 +08:00 4327 次点击
    这是一个创建于 1890 天前的主题,其中的信息可能已经有所发展或是发生改变。

    前端时间在开发 [葡萄城社区] 公众号时有一个功能是需要用网页授权认证地址生成二维码,但类似像下面这样的 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

    下面分别对使用到的这三个包简单说明一下:

    • 在这个应用中,我们使用了 mongodb,之所以选择它是因为执行高效且低开销,所以执行起来也很高效,不过如果使用其他数据库也是没问题的。这里的mongoose就是 npm 的一个包,主要是为程序提供连接 mongodb 并增删查改的功能。
    • 通过使用shortid可以生成一个指定字符不重复的编码,便于我们生成类似 xxx.com/ngTsfdgh 类似红字部分的编码。
    • 由于我们生成短链接部分的 api 使用的是 post 方法,使用body-parser可以多扩展一种 body 编码类型解析能力。

    首先设置 MongoDB 的连接信息

    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);

    定义 express 路由

    因为这个应用我们只有生成和 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 即可自动安装所有依赖,如果大家有问题,可通过评论区告诉我。

    源码下载>>

    opengps
        1
    opengps  
       2020-09-25 09:36:54 +08:00 via Android
    首先得有一个短域名,我找了好几年只看好一个中意的(4 位 cn),已在个人网站下用了 3 年
    memedahui
        2
    memedahui  
       2020-09-25 09:37:14 +08:00   1
    easonHHH
        3
    easonHHH  
       2020-09-25 09:42:11 +08:00
    直接拷贝代码是真的没有看下来的欲望,建议代码块格式一下
    xuxuxu123
        4
    xuxuxu123  
       2020-09-25 09:47:30 +08:00
    有个,四位 .com 域名;
    65we.com
    有需要的嘛
    yamedie
        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 执行后面的语句, 这里直接写成同步写法了, 让我有点摸不着头脑
    justseemore
        6
    justseemore  
       2020-09-25 09:50:35 +08:00
    yourls 不香么。。
    shc
        7
    shc  
       2020-09-25 09:51:17 +08:00 via Android
    感谢楼主的教程,那就搭车出几个短域名吧,pp.tc, mv.mk, 58.si, us.rs, vps.vc, git.tg, sir.sr, ts.st ,感兴趣的私聊
    GrapeCityChina
        8
    GrapeCityChina  
    OP
       2020-09-25 09:53:21 +08:00
    @yamedie 你的建议很好,你这样会使效率更高,这也是一个可优化的点
    ylsc633
        9
    ylsc633  
       2020-09-25 10:11:15 +08:00
    那我也搭车出个域名?

    guof.com

    tsvv.com
    qq-v.com
    linstrong
        10
    linstrong  
       2020-09-25 10:26:25 +08:00
    之前在网上找了一个 MyURL 的短网址程序,傻瓜式安装,唯一的缺点就是没有后台,用了一个两位的.cm 域名搭建了一个,感觉还行
    heheda0
        11
    heheda0  
       2020-09-25 10:56:57 +08:00
    之前用 go 做了一个 http://url.2048ai.cn/short_url
    zsdroid
        12
    zsdroid  
       2020-09-25 11:01:28 +08:00
    先把 t.tt 买了,再来谈短链接生成平台
    zhuweiyou
        13
    zhuweiyou  
       2020-09-25 11:49:24 +08:00
    缺的是程序吗?
    我缺的是短域名
    JavaIO
        14
    JavaIO  
       2020-09-25 12:06:48 +08:00
    有个短域名不容易
    coloz
        15
    coloz  
       2020-09-25 15:03:40 +08:00
    短链接平台有啥商业模式不。有个 3 位短域名
    Livid
        16
    Livid  
    MOD
    PRO
       2020-09-25 15:29:54 +08:00
    @memedahui 谢谢举报。这个主题已经被移动到 /go/promotions 并被下沉。
    tercel36524
        17
    tercel36524  
       2023-12-31 17:00:21 +08:00
    https://www.369url.cn/ 这个可以的
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     846 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 22ms UTC 20:51 PVG 04:51 LAX 12:51 JFK 15:51
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86