附件下载行为差异:本地流式输出 vs 云存储 302 跳转
学完这篇,你能分清 Clara BBS 里「本地流式输出」和「云存储 302 跳转」两种附件下载模式的差别,知道各自的坑在哪,出问题时会按顺序排查。
第一步:先弄清两种模式在干什么
本地流式输出:文件存在服务器自己的 uploads 目录里。用户点下载 → 请求打到 index.php → PHP 先做权限、货币、附件定价的校验 → 校验通过后用 readfile() 一类的方式把文件内容「一块块吐给」浏览器。整个过程文件始终经过 PHP 进程。
云存储 302 跳转:文件躺在对象存储/云存储上。用户点下载 → 请求还是先打到 index.php → 权限和扣费校验照旧 → 校验通过后,PHP 不读文件,只返回一个 302 响应头,把浏览器指到云存储生成的临时直链上,真正的字节由云存储直接发给用户。
一句话概括:校验都在 PHP 里做,区别在于「字节由谁发」。前者服务器扛带宽和 CPU,后者几乎不占服务器资源。
第二步:确认你的站走的是哪种模式
进后台「系统设置→云存储」,看是否启用、填了哪家的接入信息。启用且信息填写正确 → 走 302;没启用或配置为空 → 回落到本地流式输出。
注意:同一个站可能两种模式并存——老附件是本地存的,新上传的走了云。别看到「有的附件慢、有的快」就以为是随机 bug,先看附件本身存在哪。
第三步:网盘链接模式是第三种,别混为一谈
后台还支持「网盘链接模式」附件:只存链接和提取码,不占服务器存储,下载时跳到第三方网盘页面。
它和云存储 302 的差别是本质性的:
- 云存储 302:跳到你自己对象存储的签名直链,虽然地址变了,但仍是站内的可控资源,权限和计费在跳转前已经算清。
- 网盘链接:跳到外部平台,对方有没有限速、要不要登录、链接会不会失效,你完全管不了。
注意:网盘链接模式没法做「下载后才扣费」这种精细记账,因为字节不在你手上。要卖钱的附件,优先用云存储或本地存储。
第四步:本地流式输出的常见坑
- 大文件卡死或中断:PHP 要读完整个文件才结束,PHP 的
max_execution_time太短会被掐断。附件几百 MB 时,调到 300 秒以上。 - 内存告警:正规写法是分批读、边读边吐,不该把整个文件读进内存。如果你的站下载大附件时 PHP 内存爆掉,先怀疑是不是输出了多余缓冲。
- 前面有 BOM 或多余输出:下载下来的文件打不开、开头多几个乱码字符,几乎都是文件里多了空白行或 BOM。这一条是 PHP 下载最经典的坑。
- 带宽吃满:每个下载都占用一个 PHP 进程和一份出口带宽,附件热门时服务器会很吃力,这正是升级到云存储的理由。
- 上传的格式限制与下载无关:后台「上传限制」里有两个独立字段——「允许的扩展名」管图片,「附件允许的扩展名」管附件。改了图片规则不会影响附件能否上传。
第五步:云存储 302 跳转的常见坑
- 签名链接过期:临时直链一般有有效期,用户把链接复制走、过一阵再点就 403。这是正常现象,不是权限 bug。
- HTTPS 混合内容:站点是 https,云存储返回的直链如果是 http,浏览器会拦。把云存储的访问域名也配上 https。
- 防盗链拦住了自己:云存储侧若开了 Referer 白名单,必须把站点主域名加进去;否则站内点击也跳过去就 403。
- 下载统计归零:字节由云存储发出,服务器端日志看不到完整下载行为,流量统计会偏少,别拿它当准数。
- 下载器/内置浏览器处理 302 不规律:某些手机内置浏览器、第三方下载工具对 302 跟随策略不一致,会出现「点了没反应」。让用户换浏览器试一次即可确认是不是这个原因。
- 签名 URL 带不上 Cookie 也无所谓:权限已经在跳转前校验完了,直链本身就是凭据,所以别把直链往外贴——贴出去等于把文件公开了。
第六步:两者的共同点,别漏了
- 权限判定在前:附件可设「所有人/会员/指定用户组」下载,判定不通过压根不会走到输出或跳转那一步。
- 付费附件:附件可单独定价,走统一记账。计费发生在校验阶段,两种模式下都一样。
- CSRF:触发下载的按钮如果是表单提交,会带 token;出现「页面已过期,请刷新后重试」是 CSRF 没过,不是存储问题。
- 删除与恢复:前台删帖进回收站保留 30 天,附件随帖走,别急着去对象存储里手删文件。
第七步:按现象对号入座
| 现象 | 大概率原因 |
|---|---|
| 小文件正常,大文件中断 | 本地模式,PHP 超时或被网关掐断 |
| 下载下来文件打不开、开头有乱码 | 本地模式,输出前有 BOM/空白 |
| 点下载后地址栏跳到陌生域名 | 云存储 302 或网盘链接模式 |
| 复制链接过一会再点打不开 | 云存储签名链接过期 |
| 跳过去显示 403 | 云存储防盗链白名单没加站点域名 |
| 下载成功但后台没记录 | 云存储模式,统计口径不同 |
小结
- 两种模式的共同点:权限、货币、定价判定都在 PHP 层先做完;区别只在字节由谁发。
- 本地流式输出吃的是服务器带宽和 PHP 进程,怕超时、怕 BOM、怕大文件。
- 云存储 302 省资源,但要注意签名有效期、https 一致性、Referer 白名单,且统计不完整。
- 网盘链接模式是第三种,最省存储也最不可控,不适合做付费下载。
- 排查顺序固定:先确认文件存在哪(后台「系统设置→云存储」)→ 再确认权限与计费是否通过 → 最后才看网络层。
转载请注明出处,版权归原作者所有。
星耀SVIP
管理员
黑卡会员






