# 123云盘上传模式 & 竞品分析 > 来源:分析 Skillhub 上 `123pan-upload` skill 的实现,提取可借鉴的模式。 ## 短直链生成(Short Direct Link) 直链 URL 包含 user_id 和文件路径,较长且暴露用户信息。短直链只用 file_id,更隐私友好: ```python import base64, json def get_user_id_from_token(token: str) -> int: """从 JWT token 解析 user_id,无需额外 API 调用""" parts = token.split(".") if len(parts) >= 2: payload = parts[1] padding = 4 - len(payload) % 4 if padding != 4: payload += "=" * padding data = json.loads(base64.b64decode(payload)) return data.get("id", 0) return 0 def get_short_direct_link(user_id: int, file_id: int) -> str: return f"https://{user_id}.v.123pan.cn/{user_id}/{file_id}" ``` **对比:** | 类型 | URL 格式 | 隐私性 | 可直链下载 | |------|---------|--------|-----------| | 分享链接 | `https://www.123pan.com/s/{shareKey}` | ✅ 好 | ❌ 需跳转 | | 完整直链 | `https://{user_id}.v.123pan.cn/{user_id}/{file_id}/{filename}` | ⚠️ 暴露路径 | ✅ | | 短直链 | `https://{user_id}.v.123pan.cn/{user_id}/{file_id}` | ⚠️ 暴露 user_id | ✅ | ## 上传流程(V2 API) > ⚠️ **2026-05 验证**:以下流程经过实际 API 调用验证,修正了早期文档中的错误。 ### 两个域名 | 域名 | 用途 | 端点 | |------|------|------| | `https://open-api.123pan.com` | 主 API(认证、文件管理、chunked create) | `/api/v1/*`, `/api/v2/*`, `/upload/v2/file/create` | | `https://openapi-upload.123242.com` | 上传专用(获取上传域名返回此值) | `/upload/v2/file/single/create`, `/upload/v2/file/slice`, `/upload/v2/file/upload_complete` | 获取上传域名:`GET /upload/v2/file/domain` → 返回 `["https://openapi-upload.123242.com"]`(列表,非对象) ### 单文件上传(<100MB) ``` 1. GET open-api.123pan.com/upload/v2/file/domain → 获取上传服务器地址 2. POST openapi-upload.123242.com/upload/v2/file/single/create → multipart/form-data 上传 ``` **关键坑点**: - `single/create` **必须用 multipart/form-data**,不能用 JSON body。JSON 会导致 500 服务器崩溃。 - 表单字段:`parentFileID`(text), `filename`(text), `etag`(text), `size`(text), `file`(file) - `duplicate` 字段:**不要传 `0`**(会导致 "duplicate参数错误")。不传默认覆盖,或传 `1`(重命名)/`2`(覆盖)。 - 响应:`{"code":0, "data":{"fileID": 12345, "completed": true}}` — 无需额外上传步骤。 ### 分片上传(100MB-10GB) ``` 1. POST open-api.123pan.com/upload/v2/file/create → 创建上传任务(主域名) 2. POST openapi-upload.123242.com/upload/v2/file/slice → 逐片上传(上传域名) 3. POST openapi-upload.123242.com/upload/v2/file/upload_complete → 完成上传(上传域名) ``` **关键坑点**: - `create` 调用主 API 域名,不是上传域名! - `slice` 和 `upload_complete` 调用上传域名。 - `slice` 请求体字段名为 `partMd5`(注意:不是 `sliceMD5`,后者会导致 500)。 - 分片大小由 `create` 响应中的 `sliceSize` 决定(通常 16MB)。 ### SHA1 秒传 ```python # create_file 响应中 reuse=true 表示文件已存在,跳过上传 if create_result["reuse"]: return {"file_id": create_result["file_id"], ...} ``` ### 上传校验轮询 ```python # upload_complete 响应中 completed=false 时需轮询 # 建议间隔:1 秒 # 最大等待:~5 分钟/GB(10GB 文件约 50 分钟) # 文件大小越大,校验时间越长 for attempt in range(max_retries): resp = api_post("/upload/v2/file/upload_complete", {"preuploadID": preupload_id}) if resp["data"].get("completed"): return resp["data"] # 校验完成 time.sleep(1) # 按 API 文档要求,每秒轮询一次 ``` ### MD5 作为 Etag 上传创建时需要提供文件的 MD5 作为 `etag` 字段: ```python import hashlib etag = hashlib.md5(open(file_path, "rb").read()).hexdigest() ``` ## WebDAV 上传(>10GB 文件) API 上传上限 10GB,超大文件可用 WebDAV + rclone: ```bash # 1. 配置 rclone(隔离配置,避免读取其他云服务凭证) rclone config --config ~/123pan-rclone.conf # 添加 "123pan-webdav" remote # 2. 上传 RCLONE_CONFIG=~/123pan-rclone.conf rclone copy /path/to/large/file 123pan-webdav:/folder -P # 3. 上传后通过 API 查找文件(WebDAV 上传有 30-90 秒索引延迟) # 需要轮询 file/list 接口等待文件出现 ``` **注意:** WebDAV 上传后文件不会立即出现在 API 列表中,需要重试查找(最多 30 次,每次间隔 3 秒)。 ## 安全实践 - rclone 配置隔离:用 `RCLONE_CONFIG` 环境变量指定独立配置文件 - 凭证存储:用环境变量或 `.env` 文件,不要硬编码 - Token 刷新:123yunpan.py CLI 已自动处理 401 响应时的 token 刷新