一个简单的短链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 替换为你的真实域名。
 





