后台媒体库点「添加」选了一张图,进度条走到一半卡住,或直接报「上传失败 / HTTP 错误 / 超过了此站点的最大上传大小」------有时整页一直转圈,刷新后库里什么也没有。这和今天已写过的「登录后跳回登录页(Cookie / CDN)」「Elementor 编辑器空白」「前台 502/503(PHP-FPM)」「白屏 / 严重错误(Fatal / 插件二分)」「Shopify 结账按钮灰色」「WP-Cron 定时不准点 / 备份从不跑」不是一类故障:那些卡在会话、编辑器资源、网关、PHP 应用层、结账脚本或 Cron 触发;这里卡在 上传链路------PHP 体积限制、临时目录与 uploads 权限、安全插件 / WAF 拦 multipart、对象存储 Offload、CDN 缓存,以及浏览器侧大文件超时。
更稳的顺序是:先分清是 体积超限 / 目录不可写 / 安全层拦截 / Offload 远端失败 / CDN 或浏览器超时 → 用站点健康或 phpinfo / 主机面板核对 upload_max_filesize、post_max_size、memory_limit、max_execution_time → 查 wp-content/uploads 属主与权限 → 临时停安全插件 / 放行 multipart → 查 Offload / S3 类插件凭证与桶策略 → 绕过 CDN 源站直传验收 → 最后用一张略小于限额的图与一张略超限额的图做对照。别一上来就重装媒体插件,也别在未看 PHP 限额时反复换主题。
很多站在换主机、开 CDN、上对象存储、或收紧安全插件规则之后才「突然」传不上去:以前 5MB 图没问题,现在 2MB 也转圈。根因通常不在「媒体库坏了」,而在 上传请求在某一层被拒或超时------PHP 先截断、目录写不进、WAF 当攻击拦、或 Offload 远端返回 403,表现都像「上传失败 / 一直转圈」。
先分清:超限 / 不可写 / 被拦 / Offload 挂 / 浏览器超时
「媒体库传不上去」常见落在五条线上,别和登录环、502、白屏、Cron 混着改:
- PHP 上传限制 :
upload_max_filesize小于文件;或post_max_size≤upload_max_filesize(后者更大也没用,POST 体先被截断);memory_limit/max_execution_time过小也会在生成缩略图阶段挂掉。 - 目录权限与属主 :
wp-content/uploads(及当年月子目录)对 PHP-FPM / Apache 运行用户不可写,或属主是 root、部署用户却是www-data,表现多为失败或空响应。 - 安全插件 / WAF / 主机防火墙 :multipart 被当成异常请求;文件类型黑名单过严;ModSecurity / 云 WAF 规则拦
.php伪装检测误伤图片。临时停安全插件能立刻成功,多半落在这层。 - 对象存储 / Offload 插件:媒体已接到 S3 / OSS / COS,本地只留 stub。远端密钥过期、桶区域写错、CORS / ACL 拒写时,后台会转圈或报模糊「HTTP 错误」。
- CDN / 浏览器 / 网络:上传打到 CDN 边缘被缓存策略干扰、或超大文件在弱网下超时;无痕窗口直连源站 IP / 临时关 CDN 可对照。
另记易混项:小图能传、大图失败 → 优先 PHP 限额与超时;任意大小都失败且无错误文案 → 优先权限、安全拦截、Offload;仅某格式(如 WebP / SVG)失败 → 类型白名单与安全插件。
第一步:核对 PHP 上传限额 ------ 三个数必须同时够用

用管理员打开 工具 → 站点健康 → 信息 → 服务器,或主机面板 PHP 设置,记下:
upload_max_filesize:单文件上限(常见默认 2M / 8M,生产站建议按业务调到 32M~64M,勿无脑 512M)。post_max_size:必须大于upload_max_filesize(习惯上至少大一档,如 40M / 64M),否则大 POST 在进 WordPress 前就被 PHP 丢弃,媒体库只看到失败。memory_limit:生成多尺寸缩略图时吃内存;图很大或装了重处理插件时,128M 可能不够,可临时提到 256M 验证。max_execution_time/max_input_time:大图或批量上传超时会出现「转圈后失败」;维护窗口可临时加大再收回。
预期定界:
- 限额明显小于你的文件 → 先改 PHP,不要先动插件;
- 限额够用、小图也失败 → 进第二步目录与第三步安全层;
- 改完限额仍只大图挂 → 再看内存与执行时间。
最小配置片段(生产务必可回滚)
若主机允许 .user.ini(PHP-FPM / CGI 常见)或面板「PHP 配置」:
ini
; .user.ini 示例 ------ 改前备份;改后等面板刷新或重载 PHP
upload_max_filesize = 64M
post_max_size = 64M
memory_limit = 256M
max_execution_time = 120
max_input_time = 120
php.ini 同名字段亦可;部分主机只认面板开关,改文件无效。wp-config.php 不能 覆盖 upload_max_filesize(那是 PHP 层),但可设:
php
@ini_set( 'upload_max_filesize', '64M' ); // 多数共享主机无效,仅作尝试
define( 'WP_MEMORY_LIMIT', '256M' );
改完用站点健康或新建 phpinfo 临时页确认生效,测完立刻删 phpinfo。数值按业务收敛,避免「临时调试值」留在生产。
主机面板若同时提供「上传限制」与「PHP 配置」两处开关,以实际 phpinfo 读数为准;面板显示 64M、站点健康仍是 2M,说明站点目录下的 .user.ini / .htaccess 覆盖了面板,或 PHP-FPM 池未重载。共享主机改完后常需等 1~5 分钟,或在面板点「重启 PHP」。多站点网络还要看「网络设置 → 上传文件大小限制」,它会在应用层再砍一刀,与 PHP 限额取更严者。
第二步:uploads 目录 ------ 属主、权限、磁盘与 inode
SSH 或主机文件管理打开 wp-content/uploads:
- 属主应与 PHP 运行用户一致(常见
www-data、nginx、面板用户);部署脚本若用 root 解压,会导致子目录不可写。 - 目录权限常见
755、文件644;部分环境需要775/ 组写,不要 整树777留作长期方案。 - 磁盘满、inode 耗尽时,上传会静默失败------
df -h/df -i看一眼。 - 当年月子目录(如
2026/10)若被安全策略锁成只读,新建月份会失败;确认 WordPress 能自动创建年月目录。
预期 :用同一 PHP 用户 touch wp-content/uploads/_write_test 能成功,删测试文件;媒体库再传一张小 PNG。
容器 / 只读根文件系统部署时,确认 uploads 挂载为可写卷;CI 发布若每次覆盖整个 wp-content,可能冲掉年月目录权限或 SELinux 上下文(ls -Z 对照)。符号链接把 uploads 指到共享存储时,还要核共享盘的挂载选项是否含 noexec/ro 误伤(一般上传不需要 exec,但只读会直接失败)。
第三步:安全插件、WAF、主机防火墙 ------ multipart 最易被误伤
上传是 multipart/form-data,安全层误判率高于普通后台请求:
- 临时停用 Wordfence / iThemes / 国产安全套件等(维护窗口),再传同一张图。立刻成功 → 问题在规则,不在 PHP。
- 在安全插件里放行:媒体上传路径、
async-upload.php、管理员 IP;检查「文件类型」「恶意文件扫描」是否误伤 WebP / 大 JPEG。 - 云 WAF / 主机 ModSecurity:看拦截日志时间戳是否对齐上传动作;对
/wp-admin/async-upload.php与 REST 媒体端点做例外(测完再收紧)。 - 隐藏登录、二次验证插件偶发打断上传 iframe / XHR------对照无痕 + 仅管理员账号。
安全插件与主题/上传链路冲突时,把「主机限制 → 目录 → 安全拦截 → Offload」放在同一条链上排查,可参考 媒体上传与主机/插件侧的分层排查,避免只重装媒体库插件却不动拦截层。
第四步:对象存储 / Offload ------ 远端写失败也会像「转圈」
若启用了 WP Offload Media、同类 OSS/COS/S3 插件,或主题自带远端存储:
- 看插件状态页:凭证、区域、桶名、路径前缀是否仍有效;密钥轮换后常忘更新。
- 桶策略需允许当前密钥
PutObject(及缩略图所需写权限);公共读私有写要分清。 - 临时改回「本地存储」或暂停 Offload,再传一张图:本地成功、开 Offload 失败 → 定界在远端。
- CORS 主要影响浏览器直传场景;经 WordPress 中转上传时优先查服务端凭证与网络出站(主机是否禁外连)。
预期 :Offload 日志或云控制台能看到对应 PutObject 成功;失败则记下错误码(403/404/签名过期)再改配置。
第五步:CDN、浏览器、网络 ------ 对照源站直传
- 临时绕过 CDN(回源 Host / hosts 指源站 / 面板「开发模式」),用无痕窗口登录后台再传。
- 换浏览器、关广告拦截与「隐私类」扩展;大文件在弱网下易超时,可先压图再传。
- 开发者工具 Network 看
async-upload.php:状态码 413 → 网关/PHP 体积;403 → WAF/权限;500 → PHP Fatal(回查错误日志与内存);pending 一直转 → 超时或被中间层掐断。 - 多站点 / 子目录站确认上传落到正确站点的
uploads路径,避免写到别的博客目录。
移动端或平板后台上传偶发失败时,先在桌面浏览器复现,避免把「触控上传组件兼容」和「服务端限额」缠在一起。若仅 REST API / 应用密码上传失败而浏览器媒体库正常,查应用密码权限与 REST wp/v2/media 是否被禁用。
常见误操作(尽量避开)
- 只改
upload_max_filesize,不改更大的post_max_size------POST 仍被截断。 - 整树
chmod 777当长期方案:能传上去,但把写权限敞给所有用户。 - 未备份
.user.ini/ 面板 PHP 值就连改数档,出问题无法单条回滚。 - 安全插件与 Offload 同时「大修」:一次改两层,无法定界;维护窗口建议一次只动一层。
- 把 Elementor / 页面构建器「插图失败」当成媒体库坏了:先在 媒体 → 添加 验证原生上传,再查构建器自身请求。
第六步:验收清单(无软广,只验结果)
同一维护窗口建议勾完下面几项再收工:
- 站点健康 /
phpinfo:upload_max_filesize<post_max_size,且两者与业务目标一致;memory_limit足够生成缩略图。 uploads:属主正确;测试写文件成功;磁盘与 inode 正常。- 安全层:维护窗口内对照「停插件能传 / 开插件按规则放行后仍能传」;WAF 日志无对齐拦截。
- Offload(若在用):暂停远端时本地可传;恢复远端后云端可见对象且前台 URL 可访问。
- 对照上传:一张略小于限额的图成功并生成缩略图;一张略超限额的图应得到明确「超过最大上传大小」类提示,而非无限转圈。
- 变更可回滚:记下改过的 PHP 值、目录权限、安全放行项、Offload 开关,出问题能单条撤回。
把「PHP 限额 → 目录权限 → 安全拦截 → Offload → CDN/浏览器」按顺序走完,大多数「上传失败 / 一直转圈」会落在前三步之内。与登录 Cookie、Elementor 资源、502、Fatal 白屏、Shopify 结账、WP-Cron 分界清楚,就不必在错误层反复重装媒体插件。