如何使用next.js开发网址缩短服务

701 阅读2分钟

一、什么是网址缩短服务

网址缩短服务,是把很长的网址,进行缩短,从而更利于分享与传播。

二、网址缩短的原理是什么?

网址缩短不同于图片压缩,并不是靠什么算法把字符串进行压缩,而是通过数据库,使用一个短的唯一编码,去对应原始的网址,当请求短网址是,系统会根据传递的参数,获得真正的网址,并进行跳转。

举个例子,我使用http://0ut.pw 网址缩短服务,对我的https://github.com/codetyphon/nextshort进行缩短,得到一个链接是 0ut.pw/6LAzO ,比之前的github地址短太多。

三、使用next.js开发网址缩短服务

next.js是react的服务端渲染框架。使用next.js,可以直接用前端的方法写后端。next.js的特点是,不需要配置路由,只需要根据其规则,命名js文件,就可以实现路由的效果。

1、第一个路由,/xxx。其中xxx就是缩短的唯一编码。

在pages文件夹下面,建立一个名为[slug].js的文件。 需要注意的是,要import useRouter。

import { useRouter } from 'next/router';

获得参数的方式很简单:

const router = useRouter()
const { slug } = router.query

这样,就可以通过http://ip/xxx的方式访问了。

2、根据参数,获得真实的网址

首先引入nedb,是一个很简单的kv数据库,很适合网址缩短。

var Datastore = require('nedb');
let db = new Datastore({ filename: './db', autoload: true });

用参数进行查询,如果查到,则跳转。

db.findOne({ slug: slug }, function (err, doc) {
    if(doc!=null){
        window.location.href=doc.url;
    }
});

3、唯一的编码是怎么来的?

随机数不是一个好方法,因为随机数容易重复。时间戳+随机数,或许是一个好方法,但是它并不短。

为了让它短,通常采用的是10进制转62进制(代码来源于网络)。

function string10to62(number) {
    var chars = '0123456789abcdefghigklmnopqrstuvwxyzABCDEFGHIGKLMNOPQRSTUVWXYZ'.split(''),
      radix = chars.length,
      qutient = +number,
      arr = [];
    do {
      let mod = qutient % radix;
      qutient = (qutient - mod) / radix;
      arr.unshift(chars[mod]);
    } while (qutient);
    return arr.join('');
}

这样,只需要在数据库里设置一个自增的值,就可以用它生成唯一的短编码。

4、避免链接无效

其实就是检查url是不是url,这里不用正则,而是用构建url是否异常来判断。

function isValidUrl(url) {
    console.log('check',url);
    try {
      new URL(url);
    } catch (_) {
      return false;  
    }
    return true;
}

5、新增,及更新自增。

const post=()=>{
        if(isValidUrl(url)){
            let db = new Datastore({ filename: './db', autoload: true });
            console.log(url);
            db.findOne({ _id: 'ai' }, function (err, doc) {
                console.log('_id',doc);
                if(doc==null){
                    db.insert({_id:'ai',value:10000000}, function (err, newDoc) {
                    db.insert({type:'url',slug:string10to62(10000000),url:url,time:Date.now()}, function (err, newDoc) {
                            show(newDoc);
                        });
                    });
                }else{
                    db.update({ _id: 'ai' }, { $set: { value: doc.value+1 } }, {}, function () {
                    });
                    db.insert({type:'url',slug:string10to62(doc.value+1),url:url,time:Date.now()}, function (err, newDoc) {
                        show(newDoc);
                    });
                }
            });
        }
    }

开发完毕后,界面如下:

最后,全部代码在:github.com/codetyphon/…

可以在线体验:nextshort.vercel.app

因为在线体验的是沙盒部署,因此生成的短链接只能自己访问,无法分享给他人。

如果你在自己的服务器上部署,则可以分享给他人。