node实现短链接服务(生成短链+短链重定向到长链)

1. 短链接是啥?

这里我拿得到App某个页面的分享来举例。
例如我在得到App找到罗振宇老师的文明之旅节目,并分享到飞书,就是下面这样:
在这里插入图片描述
那么这个分享链接是什么呢?
在分享的时候也可以选择复制分享链接,这样我们就可以拿到分享链接是什么了。
在这里插入图片描述

复制下来的链接是:https://d.dedao.cn/F87jVXtsGZKCvPSI可以看到,这个链接很简短,很优雅,这就是所谓的短链接。
那么,有短链接也就有长链接啦?
是的,我们在飞书点开分享的链接,来到分享页面:
在这里插入图片描述
然后在这个页面点击右上角的三个点,复制该分享页面的链接。
在这里插入图片描述
复制到链接是:https://www.dedao.cn/share/course/article?id=nAge3MrB5aPdV5nzroJwD2ky4jvENQ&trace=eyJzX3BpZCI6IjEwODc1OSIsInNfcHR5cGUiOiI2NSIsInNfdWlkIjo0NzcwODkyMTJ9
显然这是长链接,不够美观。

2. 短链接有啥用?

  • 字符空间节省
    短链接通过将长URL转换为短标识符,大大减少了字符空间的占用。这对于在字符数受限的平台,如短信、二维码等,是非常重要的。
  • 美化和简化
    短链接提供了更美观和易读的方式来分享链接。长URL通常包含大量的字符和参数,短链接使得链接更为整洁,提高了用户体验。
  • 个性化定制
    一些短链接服务提供了自定义短链接的功能,用户可以根据需要为链接添加个性化标识符,使链接更具个性。

3. 实现短链接的核心原理是什么?

在这里插入图片描述
答案是:映射。
将需要的长链生成对应的短链,你可以把这个映射关系放在缓存、也可以放在数据库。然后,每次访问短链的时候,都需查到这个对应关系,并重定向到真正长链接对应的网址。

短链接服务包含两个部分:短链接生成和通过短链接访问原链接,主要流程如下:

短链接生成
  • 使用哈希算法、自增计数等将长URL映射到短标识符,并且短标识符应该足够短以便于记忆和传播。
通过短链接访问原链接
  • 一般使用 HTTP重定向的方式。当用户访问短连接时,服务器通过HTTP重定向将其引导至原始URL。

4. 生成短链有哪些方法?

  1. 哈希函数: 使用哈希函数对长URL进行哈希运算,得到固定长度的哈希值,然后将哈希值截取为短标识符。常用的哈希函数有MD5、SHA-1、SHA-256等。这种方法的优势在于生成的标识符是固定长度的,且具有较好的均匀性,但哈希算法是确定性的,相同的输入始终产生相同的输出,这使得短链接相对可预测且不易记忆。
  2. 自增计数: 使用一个自增的计数器作为短标识符。每次生成短连接时,计数器加一,将其转换为适当进制的字符串作为短标识符。这种方法简单直观,但可能存在预测性问题,容易伪造。
  3. 随机生成: 生成一个随机字符串作为短标识符。这种方法简单且不易被预测,但可能导致短标识符的冲突。
  4. 基于关键字的生成: 使用关键字或自定义标识符作为短标识符,例如使用文章标题、关键词的缩写等,使短链接更具易记性,但可能导致短标识符的冲突。

5. 实现步骤

  1. 初始化项目目录,安装所需依赖。
    需要四个依赖:
    express (起服务用的)
    knex (orm库,使用js语法操作mysql用的)
    mysql2 (node连接mysql用的)
    shortid (生成短链接用的,生产环境可以详细探讨短链生成算法和规则)
    在这里插入图片描述
  2. 代码附上
import express from "express";
import knex from "knex";
import shortid from "shortid";

// 连接数据库
const db = knex({
  client: "mysql2",
  connection: {
    host: "127.0.0.1",
    user: "root",
    password: "rootroot",
    database: "short_link",
  },
});

const app = express();

app.use(express.json());

app.post("/create_url", async (req, res) => {
  // 生成短码
  const short_id = shortid.generate();
  console.log("short_id:", short_id);
  // 接收前端传来的长地址
  const long_url = req.body.url;
  // 直接建立这长地址和短码的映射关系 入库
  await db("short").insert({
    short_id,
    url: long_url,
  });
  // 响应给前端短链接(协议+域名+短码)
  res.json({
    code: 200,
    short_url: `http://127.0.0.1:3000/${short_id}`,
  });
});

// redirect 前端访问短链接 则重定向至长链接
app.get("/:short_id", async (req, res) => {
  // 获取短码
  const short_id = req.params.short_id;
  // 查库,获取该短码映射的长地址
  const result = await db("short").select("url").where({
    short_id,
  });

  console.log("result:", result);
  if (result && result[0]) {
    //  重定向到长地址
    res.redirect(result[0].url);
  } else {
    res.json({
      code: 404,
      msg: "短码有问题",
    });
  }
});

app.listen(3000, () => {
  console.log("server is running at port 3000");
});

  1. 测试 (我使用的是ApiFox,当然你也可以用Postman或者其他工具)
    你可以到网上找一个长链接,我用的还是刚刚从得到分享页复制来的长链接。
    在这里插入图片描述
    可以看到服务端已经响应回了短链接,我们现在访问这个短链接。
    在这里插入图片描述
    可以拿到该页面打包后的代码,在浏览上访问这个就是分享页,表明重定向成功了,今后这个短链接就可以在互联网上传播了。

在浏览器上访问:
回车前:在这里插入图片描述

回车后:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WongLeer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值