一个简单的短链API程序
以下是一个使用 FastAPI 和 SQLite 实现的简单短链 API 程序:
🔗 功能说明:
- 通过 POST 请求访问 /u?url=原网址,可以创建一个短链(如 /u/abc123)。
- 通过 GET 请求访问 /u/短码(如 /u/abc123),可以跳转到原网址。
📦 项目结构(简单版,所有代码在一个文件中):
你可以将以下代码保存为 main.py,然后运行:
pip install fastapi uvicorn
然后运行:
uvicorn main:app –reload
📄 main.py:
from fastapi import FastAPI, Request, HTTPException, Query
from fastapi.responses import RedirectResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
from pydantic import BaseModel
import sqlite3
import secrets
import string
app = FastAPI()
# SQLite 数据库初始化
DB_NAME = "shortener.db"
def init_db():
conn = sqlite3.connect(DB_NAME)
cursor = conn.cursor()
cursor.execute('''
CREATE TABLE IF NOT EXISTS urls (
id INTEGER PRIMARY KEY AUTOINCREMENT,
short_code TEXT UNIQUE NOT NULL,
original_url TEXT NOT NULL
)
''')
conn.commit()
conn.close()
init_db()
# 生成随机短码,比如 6 位字母数字组合
def generate_short_code(length=6):
chars = string.ascii_letters + string.digits
return ''.join(secrets.choice(chars) for _ in range(length))
# 短链创建接口:POST /u?url=原网址 或 GET /u?url=原网址(推荐用 POST,但为了简单,这里用 GET 参数也支持)
@app.get("/u/")
async def create_short_url(url: str = Query(..., description="要缩短的原始 URL")):
if not url.startswith(('http://', 'https://')):
url = 'http://' + url # 自动补全协议
short_code = generate_short_code()
conn = sqlite3.connect(DB_NAME)
cursor = conn.cursor()
try:
cursor.execute("INSERT INTO urls (short_code, original_url) VALUES (?, ?)", (short_code, url))
conn.commit()
except sqlite3.IntegrityError:
# 如果短码冲突(极小概率),重新生成
conn.close()
return await create_short_url(url)
conn.close()
short_url = f"http://localhost:8000/u/{short_code}" # 假设你的服务运行在本地 8000 端口
return {"original_url": url, "short_url": short_url, "short_code": short_code}
# 短链访问接口:GET /u/{short_code} --> 重定向到原网址
@app.get("/u/{short_code}")
async def redirect_to_original(short_code: str):
conn = sqlite3.connect(DB_NAME)
cursor = conn.cursor()
cursor.execute("SELECT original_url FROM urls WHERE short_code = ?", (short_code,))
result = cursor.fetchone()
conn.close()
if result:
original_url = result[0]
return RedirectResponse(url=original_url)
else:
raise HTTPException(status_code=404, detail="短链不存在")
# 可选:一个简单的界面来展示创建短链的表单(可选功能)
@app.get("/")
async def home():
return {"message": "欢迎使用短链服务!请通过 /u/?url=你的网址 来创建短链,或访问 /u/短码 来跳转。"}
# 可选:如果你想用 POST 方法创建短链,可以添加如下接口(推荐方式)
@app.post("/u/create/")
async def create_short_url_post(original_url: str):
if not original_url.startswith(('http://', 'https://')):
original_url = 'http://' + original_url
short_code = generate_short_code()
conn = sqlite3.connect(DB_NAME)
cursor = conn.cursor()
try:
cursor.execute("INSERT INTO urls (short_code, original_url) VALUES (?, ?)", (short_code, original_url))
conn.commit()
except sqlite3.IntegrityError:
conn.close()
return await create_short_url_post(original_url)
conn.close()
short_url = f"http://localhost:8000/u/{short_code}"
return {"original_url": original_url, "short_url": short_url, "short_code": short_code}
✅ 使用方式:
创建短链(推荐 POST,但本示例 GET 参数也支持):
GET 请求示例(在浏览器访问或 curl):
http://localhost:8000/u/?url=https://www.example.com
返回结果类似:
{ "original_url": "https://www.example.com", "short_url": "http://localhost:8000/u/AbC123", "short_code": "AbC123" }
之后你访问 http://localhost:8000/u/AbC123 就会跳转到 https://www.example.com
或者你也可以用 POST 方式(更标准):
请求:
POST http://localhost:8000/u/create/
Body (form-data 或 x-www-form-urlencoded): original_url=https://www.example.com返回结果同上。
访问短链:
直接在浏览器访问:
http://localhost:8000/u/你生成的短码
就会自动跳转到原始网址。
📌 注意事项:
- 本示例使用内存安全的 SQLite,数据保存在当前目录的 shortener.db 文件中。
- 短码生成采用 secrets 模块,随机且较安全。
- 默认服务运行在 http://localhost:8000,你可以部署到线上并修改代码中的域名。
- 若你想支持 xxx.com/u/xxx 这样的自定义域名访问,请确保你的服务器配置了正确的域名和反向代理(如 Nginx),并将代码中的 localhost:8000 替换为你的真实域名。