مسح رمز الاستجابة السريعة تحميل رمز الاستجابة السريعة
متجر النطاقات
اختر أنواع المنصات لتجاوز حجب الروابط
اختر أنواع المنصات المسموحة

短网址

营销短信的末尾,总挂着一串短短的链接;发微博时字符额度紧张,也没人愿意把一条上百字符的网址原样塞进去。短网址技术解决的正是这类问题——把冗长的原始链接压缩成十几个字符的短串,既省空间,分享起来也体面。顺带还有个好处:原始网址里的参数和结构被藏了起来,不至于一眼被人看穿。

这套技术的原理并不复杂,拆开看无非三件事。

第一件,生成唯一标识。常见的路子有两条:一是用 MD5、SHA-1 这类哈希算法对长网址算出固定长度的哈希值,截取一段当作短码;二是给每条链接分配一个自增 ID,再用 Base62 编码(0-9、a-z、A-Z 共 62 个字符)把数字转成短字符串。哈希方案可能撞车,得额外处理冲突;自增 ID 天然唯一,工程上更省心。

第二件,存储映射。长网址和短码的对应关系要落到数据库里,MySQL、Redis 都行;访问量一大,Redis 这类内存库的优势就会很明显。

第三件,重定向。用户点开短网址,服务端根据短码查出原始地址,返回一个 HTTP 302 状态码,浏览器自动跳过去。整个过程对用户完全透明,感知上就是"点了一下就到了"。



原理说完了,接下来动手写一个。用 Python + Flask + SQLite 搭一个最小可用的短网址服务,几十行代码就能跑起来:

import sqlite3
import string
import random
from flask import Flask, request, redirect, jsonify

app = Flask(__name__)

<h1>数据库初始化</h1>
def init_db():
conn = sqlite3.connect('short_url.db')
cursor = conn.cursor()
cursor.execute('''
CREATE TABLE IF NOT EXISTS urls (
id INTEGER PRIMARY KEY AUTOINCREMENT,
original_url TEXT NOT NULL,
short_code TEXT UNIQUE NOT NULL
)
''')
conn.commit()
conn.close()

<img src="/uploads/20251015/57.png?t=1942808886" alt="" class="img-fluid" />

<h1>生成随机短码</h1>
def generate_short_code(length=6):
chars = string.ascii_letters + string.digits
return ''.join(random.choices(chars, k=length))

<h1>生成短网址</h1>
@app.route('/shorten', methods=['POST'])
def shorten_url():
data = request.json
original_url = data.get('url')
if not original_url:
return jsonify({'error': 'URL is required'}), 400

conn = sqlite3.connect('short_url.db')
cursor = conn.cursor()

<h1>检查是否已存在</h1>
cursor.execute('SELECT short_code FROM urls WHERE original_url = ?', (original_url,))
result = cursor.fetchone()
if result:
short_code = result[0]
else:
# 生成新短码
while True:
short_code = generate_short_code()
cursor.execute('SELECT * FROM urls WHERE short_code = ?', (short_code,))
if not cursor.fetchone():
break
# 插入数据库
cursor.execute('INSERT INTO urls (original_url, short_code) VALUES (?, ?)',
(original_url, short_code))
conn.commit()

conn.close()
short_url = f'http://localhost:5000/{short_code}'
return jsonify({'short_url': short_url})

<h1>重定向到原始网址</h1>
@app.route('/<short_code>')
def redirect_to_original(short_code):
conn = sqlite3.connect('short_url.db')
cursor = conn.cursor()
cursor.execute('SELECT original_url FROM urls WHERE short_code = ?', (short_code,))
result = cursor.fetchone()
conn.close()

if result:
return redirect(result[0])
else:
return 'URL not found', 404

<img src="/uploads/20251015/10.png?t=1944321764" alt="" class="img-fluid" />

if __name__ == '__main__':
init_db()
app.run(debug=True)


代码不长,但有几个地方值得展开说说。

数据库选了 SQLite,零配置、单文件,拿来做演示再合适不过。表结构也很简单:id 是自增主键,original_url 存原始网址,short_code 存短码,并加了唯一约束,从数据库层面就把重复的可能性堵死了。

短码生成靠 random.choices,从大小写字母加数字里随机挑 6 个字符。6 位短码的理论容量是 62 的 6 次方,约 568 亿种组合,小规模使用绰绰有余。代码里还做了防重处理:生成之后先查一遍库,撞上了就重新生成,直到拿到一个没人占用的码为止。随机方案迟早会遇到冲突,这个 while 循环就是兜底用的。

接口一共两个。POST /shorten 接收 JSON 格式的长网址,返回完整的短链接。注意它先检查了这条长网址是否已经存在——如果之前缩短过,直接复用旧短码,免得同一个网址在库里堆出好几条冗余记录。另一个接口 / 负责重定向,查得到就 302 跳走,查不到就老老实实返回 404。

跑起来也不费劲。先装依赖:

pip install flask




然后启动服务:

python app.py


服务默认监听 5000 端口。用 curl 测一下生成接口:

curl -X POST -H "Content-Type: application/json" -d '{"url": "https://example.com"}' http://localhost:5000/shorten


拿到返回的短网址后,在浏览器里直接访问,比如 http://localhost:5000/abc123,就会跳到对应的原始地址。整条链路到这里就打通了。

当然,这只是个骨架版本,真要投入实际使用,还有不少功能可以往上叠。比如允许用户自定义短码,方便嵌入品牌名或活动名,自定义之前先查重就行;再比如给每条短链记录点击次数、访问来源和设备类型,对做运营的人来说,这类数据往往比链接本身更值钱。有效期也可以安排上,过期自动失效,特别适合限时活动的场景。如果是团队协作,用 Swagger 或 Postman 补一份 API 文档,能省下不少沟通成本。

性能层面也得提一句:访问量一旦上来,每次请求都去查 SQLite 肯定顶不住。生产环境的常规做法是把热点映射放进 Redis 缓存;短码生成也可以换成 UUID 或发号器方案,避免随机冲突带来的重试开销。

说到底,短网址的核心就两件事:怎么生成不撞车的唯一短码,怎么把映射关系存得又快又稳。上面的示例把这两件事都跑通了,剩下的扩展,无非是按自己的需求往上加罢了。