如果想在 V2EX 获得更好的推广效果,欢迎了解 PRO 会员机制:
https://www.v2ex.com/pro/about

如果你经常使用铜币置顶主题,持有 V2EX Solana Token 会在每日签到时获得额外铜币:
https://www.v2ex.com/solana
GrapeCityChina
V2EX  ›  推广

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

  •  
  •   GrapeCityChina · Sep 25, 2020 · 4699 views
    This topic created in 2065 days ago, the information mentioned may be changed or developed.

    前端时间在开发 [葡萄城社区] 公众号时有一个功能是需要用网页授权认证地址生成二维码,但类似像下面这样的 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  
       Sep 25, 2020 via Android
    首先得有一个短域名,我找了好几年只看好一个中意的(4 位 cn),已在个人网站下用了 3 年
    memedahui
        2
    memedahui  
       Sep 25, 2020   ❤️ 1
    easonHHH
        3
    easonHHH  
       Sep 25, 2020
    直接拷贝代码是真的没有看下来的欲望,建议代码块格式一下
    xuxuxu123
        4
    xuxuxu123  
       Sep 25, 2020
    有个,四位 .com 域名;
    65we.com
    有需要的嘛
    yamedie
        5
    yamedie  
       Sep 25, 2020
    貌似是 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  
       Sep 25, 2020
    yourls 不香么。。
    shc
        7
    shc  
       Sep 25, 2020 via Android
    感谢楼主的教程,那就搭车出几个短域名吧,pp.tc, mv.mk, 58.si, us.rs, vps.vc, git.tg, sir.sr, ts.st ,感兴趣的私聊😃
    GrapeCityChina
        8
    GrapeCityChina  
    OP
       Sep 25, 2020
    @yamedie 你的建议很好,你这样会使效率更高,这也是一个可优化的点
    ylsc633
        9
    ylsc633  
       Sep 25, 2020
    那我也搭车出个域名?

    guof.com

    tsvv.com
    qq-v.com
    linstrong
        10
    linstrong  
       Sep 25, 2020
    之前在网上找了一个 MyURL 的短网址程序,傻瓜式安装,唯一的缺点就是没有后台,用了一个两位的.cm 域名搭建了一个,感觉还行
    heheda0
        11
    heheda0  
       Sep 25, 2020
    之前用 go 做了一个 http://url.2048ai.cn/short_url
    zsdroid
        12
    zsdroid  
       Sep 25, 2020
    先把 t.tt 买了,再来谈短链接生成平台
    zhuweiyou
        13
    zhuweiyou  
       Sep 25, 2020
    缺的是程序吗?
    我缺的是短域名
    JavaIO
        14
    JavaIO  
       Sep 25, 2020
    有个短域名不容易
    coloz
        15
    coloz  
       Sep 25, 2020
    短链接平台有啥商业模式不。有个 3 位短域名
    Livid
        16
    Livid  
    MOD
    PRO
       Sep 25, 2020
    @memedahui 谢谢举报。这个主题已经被移动到 /go/promotions 并被下沉。
    tercel36524
        17
    tercel36524  
       Dec 31, 2023
    https://www.369url.cn/ 这个可以的
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   2425 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 94ms · UTC 00:38 · PVG 08:38 · LAX 17:38 · JFK 20:38
    ♥ Do have faith in what you're doing.