1. 项目概述:用FastAPI构建局域网文件与剪贴板共享工具
在团队协作或设备间传输文件时,我们常常会遇到这样的场景:需要临时传个小文件给同事,却找不到U盘;想在手机和电脑间共享剪贴板内容,却要依赖第三方云服务。传统解决方案要么需要物理介质(如U盘),要么依赖互联网服务(如微信文件传输),都存在效率和安全性的局限。
FastAPI作为现代Python Web框架,凭借其异步特性和简洁API设计,非常适合快速构建这类轻量级工具。我最近用FastAPI开发了一个局域网内的文件与剪贴板共享系统,整个过程不到30分钟,却解决了日常工作中的高频痛点。这个工具的特点包括:
- 纯局域网通信,不依赖外网和第三方服务
- 支持文件拖拽上传和下载
- 实时同步剪贴板文本内容
- 无需安装客户端,浏览器即可访问
- 基于HTTP Basic Auth的基础安全控制
2. 环境准备与FastAPI基础配置
2.1 开发环境搭建
首先确保你的Python版本在3.7+(推荐3.9+),然后创建虚拟环境:
bash复制python -m venv fastapi_share
source fastapi_share/bin/activate # Linux/Mac
fastapi_share\Scripts\activate # Windows
安装核心依赖:
bash复制pip install fastapi uvicorn python-multipart
提示:python-multipart是处理文件上传必需的依赖,容易被忽略
2.2 最小可行FastAPI应用
创建一个main.py文件,构建基础框架:
python复制from fastapi import FastAPI, UploadFile, File
from fastapi.staticfiles import StaticFiles
import uvicorn
app = FastAPI(title="局域网文件共享工具")
@app.get("/")
async def root():
return {"message": "文件共享服务已启动"}
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000)
启动服务:
bash复制python main.py
此时访问http://localhost:8000应该能看到JSON响应。关键点说明:
host="0.0.0.0"允许局域网其他设备访问- 默认端口8000,可修改为其他可用端口
- 生产环境建议增加
--reload参数方便开发调试
3. 文件共享功能实现
3.1 文件上传接口设计
在main.py中添加文件上传端点:
python复制from fastapi import HTTPException
import os
UPLOAD_DIR = "shared_files"
os.makedirs(UPLOAD_DIR, exist_ok=True)
@app.post("/upload")
async def upload_file(file: UploadFile = File(...)):
try:
file_path = os.path.join(UPLOAD_DIR, file.filename)
with open(file_path, "wb") as buffer:
buffer.write(await file.read())
return {"filename": file.filename, "saved_path": file_path}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
这个接口实现了:
- 接收文件上传(支持多文件)
- 保存到本地
shared_files目录 - 返回上传结果信息
3.2 文件下载与列表展示
添加文件列表和下载功能:
python复制from fastapi.responses import FileResponse
from typing import List
@app.get("/files", response_model=List[str])
async def list_files():
return os.listdir(UPLOAD_DIR)
@app.get("/download/{filename}")
async def download_file(filename: str):
file_path = os.path.join(UPLOAD_DIR, filename)
if not os.path.exists(file_path):
raise HTTPException(status_code=404, detail="文件不存在")
return FileResponse(file_path)
3.3 静态文件服务配置
为了让前端页面可以直接访问上传的文件,添加静态文件路由:
python复制app.mount("/shared", StaticFiles(directory="shared_files"), name="shared_files")
现在可以通过http://localhost:8000/shared/文件名直接下载文件。
4. 剪贴板同步功能实现
4.1 剪贴板存储设计
使用内存字典临时存储剪贴板内容:
python复制from pydantic import BaseModel
class ClipboardContent(BaseModel):
text: str
clipboard_store = {"content": ""}
@app.post("/clipboard")
async def update_clipboard(content: ClipboardContent):
clipboard_store["content"] = content.text
return {"status": "updated"}
@app.get("/clipboard")
async def get_clipboard():
return {"content": clipboard_store["content"]}
4.2 实时同步方案
为了实现近实时同步,可以采用两种方案:
-
轮询方案(简单实现):
前端定时(如每秒)请求/clipboard接口获取最新内容 -
WebSocket方案(更高效):
需要额外实现WebSocket端点,这里展示基础实现:
python复制from fastapi import WebSocket
@app.websocket("/ws/clipboard")
async def websocket_clipboard(websocket: WebSocket):
await websocket.accept()
while True:
data = await websocket.receive_text()
clipboard_store["content"] = data
await websocket.send_text(f"Clipboard updated: {data}")
5. 前端界面与安全增强
5.1 简易HTML界面
在项目根目录创建static文件夹,添加index.html:
html复制<!DOCTYPE html>
<html>
<head>
<title>局域网文件共享</title>
<style>
/* 基础样式省略 */
</style>
</head>
<body>
<div class="container">
<h1>文件共享</h1>
<input type="file" id="fileInput" multiple>
<button onclick="uploadFiles()">上传</button>
<h2>文件列表</h2>
<ul id="fileList"></ul>
<h1>剪贴板同步</h1>
<textarea id="clipboard" rows="5"></textarea>
<button onclick="syncClipboard()">同步</button>
</div>
<script>
// JavaScript实现省略
</script>
</body>
</html>
配置静态文件路由:
python复制app.mount("/", StaticFiles(directory="static", html=True), name="static")
5.2 基础安全措施
添加HTTP Basic认证:
python复制from fastapi import Depends, status
from fastapi.security import HTTPBasic, HTTPBasicCredentials
security = HTTPBasic()
def authenticate(credentials: HTTPBasicCredentials = Depends(security)):
correct_username = "admin"
correct_password = "password" # 生产环境应从配置读取
if (credentials.username != correct_username or
credentials.password != correct_password):
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="认证失败",
headers={"WWW-Authenticate": "Basic"},
)
return credentials.username
@app.get("/secure")
async def secure_route(username: str = Depends(authenticate)):
return {"message": f"欢迎, {username}"}
6. 部署与使用技巧
6.1 局域网访问配置
确保服务启动时绑定到0.0.0.0:
bash复制uvicorn main:app --host 0.0.0.0 --port 8000
其他设备访问时使用主机IP:
- Windows:
ipconfig查看IPv4地址 - Linux/Mac:
ifconfig或ip a
6.2 性能优化建议
-
文件上传限制:
python复制from fastapi import FastAPI, UploadFile, File, Form @app.post("/upload") async def upload_file( file: UploadFile = File(..., max_size=10_000_000) # 限制10MB ): ... -
启用Gzip压缩:
python复制from fastapi.middleware.gzip import GZipMiddleware app.add_middleware(GZipMiddleware)
6.3 常见问题排查
-
无法局域网访问:
- 检查防火墙设置(开放对应端口)
- 确认路由器没有隔离客户端
-
文件上传失败:
- 检查
shared_files目录权限 - 确认磁盘空间充足
- 检查
-
剪贴板不同步:
- 检查前端是否正常发送请求
- 确认没有跨域问题(开发模式下)
7. 扩展功能思路
这个基础工具可以进一步扩展:
- 文件预览:集成在线文档查看器
- 历史版本:保存文件修改历史
- 访问控制:基于用户的权限管理
- 通知系统:文件更新时发送提醒
- 移动端优化:响应式设计适配手机
我在实际使用中发现,这个工具特别适合以下场景:
- 设计团队快速共享素材
- 开发团队传递配置文件
- 临时会议中的资料分发
- 个人设备间的快速同步
相比传统方案,这个自建工具的优势在于:
- 完全掌控数据流向
- 不受互联网连接限制
- 可定制化程度高
- 长期使用成本低