news 2026/6/3 1:43:01

把客户照片传进了他自己的网盘,存储费几乎归零

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
把客户照片传进了他自己的网盘,存储费几乎归零

本文基于一个完整的 Node.js demo,系统讲解如何通过百度网盘开放平台 OAuth 授权,实现摄影公司将客户照片上传到客户自己的百度网盘,解决存储成本持续上涨的问题。内容覆盖应用创建、OAuth 授权流程、Token 管理、目录操作、分片上传三段式、文件预览及生产环境补强方案,可作为百度网盘开放平台对接实操手册使用。

一、问题背景:图片太多,存储费吃不消

摄影行业有个很现实的问题:图片太多了

一次婚礼、一次旅拍、一次商业拍摄,动辄几 GB、几十 GB。客户希望随时能看、能下载、能长期保存;公司如果全部放在自己的服务器或者 OSS 上,存储费、流量费、备份费都会持续上涨。

小明接到这个任务后,换了个思路:

客户本来就有自己的网盘,能不能让客户授权公司代管指定目录,公司只负责把照片上传到客户自己的网盘里?

这样一来,资料归客户自己所有,公司不用长期背负大规模存储成本;客户也能通过熟悉的百度网盘查看、下载和管理照片。

二、Demo 能力概览

当前项目是一个纯 Node.js demo,没有使用 Express。后端入口是server.js,前端页面放在public目录。

整体能力包括:

序号能力说明
1创建业务用户如"张三婚礼客户""李四写真客户"
2发起 OAuth 授权为指定用户发起百度网盘 OAuth 授权
3保存 Token授权回调后,保存 access_token、refresh_token、过期时间
4查询网盘容量检查客户网盘剩余空间
5创建目录在客户网盘中创建资料目录
6列出文件查询指定目录下的文件列表
7上传文件上传本地照片或视频到客户授权后的网盘目录
8预览文件对图片和视频做简单预览

从业务角度看,它模拟的是:摄影公司后台选择一个客户 → 让客户扫码授权百度网盘 → 公司后台把拍摄资料上传到客户自己的网盘目录

三、整体架构

3.1 项目结构

网盘demo

├─ server.js # Node 后端,处理 OAuth、上传、目录、容量、预览

├─ public

│ ├─ index.html # 页面结构

│ ├─ app.js # 前端交互逻辑

│ └─ styles.css # 样式

├─ data

│ ├─ baidu-token.json # 本地保存用户和 token

│ ├─ oauth-states.json # OAuth state 防重放记录

│ ├─ oauth-callback.log # 授权回调日志

│ └─ uploads # 前端分片上传到后端后的临时分片目录

├─ .env.example # 百度开放平台配置示例

└─ package.json

3.2 技术链路

前端页面 → Node 后端 → 百度 OAuth 授权 → 百度网盘开放接口 → 客户自己的百度网盘

/apps/{应用名}/uploads

关键点:公司服务器只承担"中转"和"调用百度接口"的角色。真正落盘的位置,是客户授权后的百度网盘,不是公司的服务器长期保存。

四、第一步:百度开放平台创建应用

4.1 获取关键参数

到百度开放平台创建应用,拿到两个关键参数:

参数说明
API Key应用的客户端标识
Secret Key应用的客户端密钥

4.2 环境变量配置

BAIDU_CLIENT_ID=你的 API Key BAIDU_CLIENT_SECRET=你的 Secret Key BAIDU_REDIRECT_URI=http://localhost:3000/oauth/callback BAIDU_APP_NAME=你的百度网盘应用名 PORT=3000

⚠️ 注意:BAIDU_REDIRECT_URI必须和百度开放平台后台配置的回调地址保持一致,否则授权完成后百度无法正确回传 code。

4.3 授权范围

Scope用途
basic基础账号授权
netdisk访问百度网盘相关能力

五、第二步:创建客户用户

Demo 页面上有"创建用户"功能。在真实业务里,这个用户对应摄影公司的客户:

客户标识客户名称
客户A王先生婚礼
客户B陈女士亲子照
客户C某品牌商业拍摄

后端接口:POST /api/users

后端会生成一个id,并把用户信息写入data/baidu-token.json

{ "id": "用户ID", "name": "客户名称", "token": null, "created_at": "创建时间" }

此时token还是空的——客户还没有授权百度网盘。

六、第三步:发起百度网盘授权

客户创建完成后,点击"授权百度网盘"。前端跳转到:

GET /oauth/start?userId=客户ID

6.1 后端处理流程

步骤操作
1检查.env里的百度应用配置是否完整
2根据userId找到当前客户
3生成随机 nonce,把 userId 和 nonce 编码成 state
4state 写入oauth-states.json,设 30 分钟有效期
5拼接百度 OAuth 授权地址,302 重定向到百度授权页

6.2 授权地址关键参数

response_type=code client_id=BAIDU_CLIENT_ID redirect_uri=BAIDU_REDIRECT_URI scope=basic,netdisk state=后端生成的 state qrcode=1 force_login=1

💡 state 不是摆设:① 知道这次授权该绑定到哪个客户;② 防止伪造回调和重复使用授权状态。force_login=1则是让客户重新确认登录身份,避免浏览器已有账号影响授权。

七、第四步:客户扫码授权,百度回调系统

客户在百度页面完成授权后,百度回调:

GET /oauth/callback?code=授权码&state=授权状态

7.1 后端回调处理

步骤操作
1解析并校验 state
2oauth-states.json消费掉这条 state,防止重复使用
3检查 state 是否过期
4用 code 调用百度 token 接口换取 token

7.2 换取 Token

https://openapi.baidu.com/oauth/2.0/token grant_type=authorization_code code=百度回传的授权码 client_id=BAIDU_CLIENT_ID client_secret=BAIDU_CLIENT_SECRET redirect_uri=BAIDU_REDIRECT_URI

百度返回成功后,保存到本地:

{ "access_token": "...", "refresh_token": "...", "expires_in": 2592000, "expires_at": "绝对过期时间" }

⚠️ 安全提醒:Demo 里 token 明文存文件,生产环境不要这样做,应该加密后存数据库或密钥系统。

7.3 自动创建目录

授权完成后,后端会自动尝试创建两个目录:

/apps/{BAIDU_APP_NAME} /apps/{BAIDU_APP_NAME}/uploads

百度网盘开放平台通常限制应用只能操作/apps/应用名目录下的文件。这个限制反而适合业务隔离——公司只管理客户授权给这个应用的目录,不碰客户网盘里的其他私人文件

八、第五步:查询客户网盘容量

前端调用:

GET /api/quota?userId=客户ID

后端请求百度接口:

https://pan.baidu.com/api/quota?access_token=xxx&checkfree=1

前端拿到totalused后计算:总容量、已使用、剩余容量、使用百分比。

💡 实践心得:上传前先看客户网盘是否还有足够空间,避免照片传到一半才失败。

九、第六步:创建客户资料目录

摄影客户的资料通常需要分组:

/apps/huanjing/uploads/王先生婚礼/原片 /apps/huanjing/uploads/王先生婚礼/精修 /apps/huanjing/uploads/王先生婚礼/视频

9.1 接口与兜底

优先级接口说明
优先xpan/file?method=create百度网盘开放平台标准接口
兜底pcs/file?method=mkdirPCS 接口兼容方案

💡 为什么要做接口兜底?百度不同接口、不同应用权限下的表现可能不完全一样。Demo 没有只押一个接口,而是做了兼容处理。

十、第七步:上传照片到客户自己的网盘

上传是整个 demo 的核心。

前端选择文件后,按 512KB 切片:

const chunkSize = 512 * 1024;

每个分片提交给后端:

POST /api/upload-chunk?userId=客户ID&dir=目标目录&filename=文件名&uploadId=上传ID&index=分片序号&total=总分片数

10.1 后端分片处理流程

步骤操作
1校验 uploadId,避免非法路径
2读取分片内容,写入本地临时目录data/uploads/{uploadId}/{index}.part
3统计已收到的分片数,未收齐则返回进度
4全部收齐后,按顺序合并成完整文件
5调用百度网盘上传接口,完成后删除本地临时分片目录

⚠️ 当前限制:合并后会把文件读入内存,限制最大 100MB。生产化时应改成流式上传或更大粒度的服务端分片调度。

十一、第八步:百度网盘上传三段式

后端真正把文件传到百度网盘时,走的是典型的三段式:

11.1 precreate:预创建

先计算文件内容的 MD5,然后调用:

https://pan.baidu.com/rest/2.0/xpan/file?method=precreate

参数:

参数说明
path目标文件路径
size文件大小
isdir是否目录(0=文件)
block_list文件 MD5 列表

返回结果:

返回值含义后续操作
return_type=2命中秒传或已有文件直接返回结果
uploadid需要继续上传进入第二步

11.2 superfile2:上传分片内容

拿到uploadid后,调用:

https://d.pcs.baidu.com/rest/2.0/pcs/superfile2?method=upload&type=tmpfile&partseq=0

Demo 里因为最终合并成一个 buffer,对百度来说只有一个上传分片,partseq0。百度上传成功后返回该分片的 MD5。

11.3 create:创建文件

最后调用:

https://pan.baidu.com/rest/2.0/xpan/file?method=create

参数:

参数说明
path目标路径
size文件大小
isdir0(文件)
rtype3(重命名策略)
uploadid上一步拿到的 uploadid
block_list文件 MD5 列表

这一步才是真正让文件出现在客户网盘目录里。

代码里还保留了上传兜底逻辑:如果开放平台上传接口不可用,会尝试 PCS 的file upload接口。

十二、第九步:查看目录和预览文件

12.1 列出文件

GET /api/files?userId=客户ID&dir=网盘目录

后端调用:

https://pan.baidu.com/rest/2.0/xpan/file?method=list

返回文件名、大小、修改时间。

12.2 文件预览

GET /api/preview?userId=客户ID&path=文件路径

后端代理请求百度下载接口,把文件流转发给浏览器:

https://d.pcs.baidu.com/rest/2.0/pcs/file?method=download

🔒 安全关键点:后端代理下载,不把 access_token 暴露给前端。前端永远不要直接持有长期有效的 access_token。

十三、接口清单一览

方法接口说明
GET/api/config获取配置
POST/api/users创建客户
GET/oauth/start发起授权
GET/oauth/callback授权回调
GET/api/quota查询容量
GET/api/files列出文件
GET/api/directories查询目录
POST/api/directories创建目录
POST/api/upload小文件直接上传
POST/api/upload-chunk分片上传
GET/api/preview文件预览

十四、业务流程总结

站在摄影公司的视角,整个流程如下:

步骤操作
1后台创建客户
2给客户一个授权入口,或现场让客户扫码授权百度网盘
3系统拿到客户授权 token
4系统自动创建应用目录和上传目录
5工作人员选择客户和目录
6上传照片、视频、精修图
7文件进入客户自己的百度网盘
8客户后续在百度网盘里自行查看、下载、长期保存

这个模式的核心不是"白嫖网盘",而是把存储责任回归给资料所有者。公司系统负责组织、上传、交付和体验;客户网盘负责长期保存。

十五、生产环境待补强能力

Demo 已经能跑通主链路,但要正式上线,还需要补强以下能力:

序号能力当前状态生产要求
Token 加密存储明文存文件存数据库,access_token、refresh_token 做加密
Refresh Token 自动续期快过期时提示重新授权过期前自动用 refresh_token 换新 token
大文件分片和断点续传合并到内存,限制 100MB流式处理、断点续传、失败重试、上传任务恢复
客户目录隔离百度应用目录天然隔离业务内部也要严格控制:A 客户不能看到 B 客户目录
完整上传任务记录增加任务表,记录客户ID、文件名、状态、失败原因、fs_id 等
合规和客户告知授权页面/协议说清:上传到应用目录、可取消授权、不访问私人文件

总结

小明这个方案,本质上是用 OAuth 把"客户自己的存储空间"接入公司业务系统。它解决的不是单纯的技术上传问题,而是摄影行业里很实际的交付和成本问题:

  • 客户要长期保存照片,公司不想无限扩容
  • 客户有自己的网盘,公司有自己的业务系统
  • 通过百度网盘开放平台,双方刚好可以连接起来

Demo 已经跑通了从创建客户、扫码授权、保存 token、创建目录、查询容量、上传文件到预览文件的完整流程。后续只要把 token 安全、自动续期、大文件上传、权限隔离和任务追踪补齐,就可以从试水 demo 逐步演进成一个真正可用的客户资料交付系统。

参考链接:

  • 百度网盘开放平台
  • 百度 OAuth 2.0 文档
  • 百度网盘开放接口文档

降本不降质,让存储回归所有者。小明已经在规划下一个客户的接入了。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/3 1:42:58

Wayland时代,为什么你的桌面离不开libinput?聊聊输入栈的演进与未来

Wayland时代,为什么你的桌面离不开libinput?聊聊输入栈的演进与未来在Linux桌面生态中,输入设备的管理一直是个复杂而微妙的话题。从早期的X11到如今的Wayland,输入处理架构经历了翻天覆地的变化。如果你曾经好奇为什么在Wayland环…

作者头像 李华
网站建设 2026/6/3 1:42:42

告别弹窗广告:高效职场人如何挑选电脑解压缩软件?

随着日常办公中接触到的文件类型越来越多,解压缩软件已经从单纯的“打包工具”,变成了影响办公效率的关键一环。很多人习惯随便在网上搜一个免费版的解压工具,结果换来的是无休止的开机弹窗和网页捆绑。面对老牌工具、开源项目和新一代应用&a…

作者头像 李华
网站建设 2026/6/3 1:42:18

如何安全备份微信聊天记录:WeChatMsg完整解决方案指南

如何安全备份微信聊天记录:WeChatMsg完整解决方案指南 【免费下载链接】WeChatMsg 提取微信聊天记录,将其导出成HTML、Word、CSV文档永久保存,对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trending/we/WeCha…

作者头像 李华
网站建设 2026/6/3 1:42:04

免费跨平台音乐播放器LX Music桌面版:你的开源音乐管家

免费跨平台音乐播放器LX Music桌面版:你的开源音乐管家 【免费下载链接】lx-music-desktop 一个基于 Electron 的音乐软件 项目地址: https://gitcode.com/GitHub_Trending/lx/lx-music-desktop 你是否厌倦了音乐软件的各种限制和订阅费用?LX Mus…

作者头像 李华