前天帮一个外贸站排障:媒体库里选一张 800KB 左右的 JPG,点上传,进度条走到一半直接弹「HTTP 错误」。文件不大,格式也正常,换 WebP、PNG 一样挂。后台其他页面都还能用,就是上传这条路不通。
这种报错几乎不带有效信息。WordPress 前端只是告诉你请求失败了,真正原因多半在 PHP 上传限制、临时目录、安全规则,或者 CDN / 反代把 async-upload.php 截掉了。别急着换主题、重装,先把现象钉死,再按层查。

1. 先复现,别猜
打开无痕窗口登录后台,F12 → Network,勾上 Preserve log,再上传一次。重点看 async-upload.php(有的环境会走 admin-ajax.php)这一条:
- 状态码:413 / 403 / 500 / 502 指向不同方向;200 但响应体不是预期 JSON,也算失败。
- Response 前几行:是 HTML 错误页、WAF 拦截页,还是空的?
- 请求大小:Content-Length 和文件实际大小是否对得上;若明显偏小,说明中途被截断。
再用两张图对照:一张 <100KB,一张 2MB 左右。小图能过、大图不行,优先查 PHP 体积限制和反代 body size;两张都不行,优先查临时目录、安全插件、WAF。
记下状态码再往下走,比盲目改配置省事。
2. 第一层:php.ini 上传相关
很多主机默认 upload_max_filesize=2M,post_max_size 甚至更小。媒体库走的是 multipart POST,两个值都要够,且 post_max_size 通常应 ≥ upload_max_filesize。同时看一下内存和超时:
ini
; 示例:按业务需要调,生产改前先备份原值
upload_max_filesize = 64M
post_max_size = 64M
memory_limit = 256M
max_execution_time = 120
max_input_time = 120
改完要确认生效的是哪份 php.ini(宝塔 / PHP-FPM 池 / 用户目录 .user.ini 容易搞混)。可在临时 phpinfo() 页搜这几个项,或用 WP 后台「站点健康 → 信息 → 服务器」对照。生产环境改 PHP 配置后记得重启对应 PHP-FPM / 服务,并马上删掉 phpinfo 测试文件。
若后台「媒体」设置里还有「最大上传文件大小」提示,以实际生效的 PHP 值为准;WordPress 自己没法突破 PHP 上限。多站点或面板「网站 → PHP」里单独配过池配置的,别只改了全局 php.ini 却忘了站点池。
有时 upload_max_filesize 看着够大,但 post_max_size 仍是 8M:multipart 整包超限时,PHP 会静默丢掉 $_FILES,前端同样只看到「HTTP 错误」。两个值一起核对,比只盯一个靠谱。
3. 第二层:临时目录、磁盘、open_basedir
PHP 先把上传写到临时目录,再挪到 wp-content/uploads。临时目录不可写、磁盘满、open_basedir 把路径挡掉,表现都可能是笼统的「HTTP 错误」。
按这个顺序核对:
upload_tmp_dir是否存在、属主是否是运行 PHP 的用户、权限是否可写(常见 1777 或属主正确的 0755)。df -h看根分区和挂载点是不是 100%;inode 满了(df -i)也会写不进去。open_basedir是否包含临时目录和wp-content/uploads;迁站后路径变了最容易漏。wp-content/uploads本身权限、是否被误设成只读,或被安全插件锁死。
临时目录若被面板改到非常规路径,建议写进 php.ini 并固定,避免每次升级 PHP 又漂回默认 /tmp(部分共享主机 /tmp 会定期清理或禁止执行)。
4. 第三层:安全插件、WAF、ModSecurity
小图大图都不行、Network 里是 403 或一页拦截 HTML,基本就落在这一层。Wordfence、iThemes、All In One WP Security,以及主机面板 / 云 WAF 的 ModSecurity,都可能对上传请求误杀------尤其是文件名带特殊字符、图片 EXIF 里夹杂脚本特征、或者你临时试着传 SVG / XML 时。
排查时建议:
- 先只停用安全类插件(不要一次关光所有插件),再试上传。
- 能过之后,逐个打开并收紧规则:给
/wp-admin/async-upload.php、必要的admin-ajax.php加例外,而不是整站关防火墙。 - 主机面板里看 ModSecurity / 防篡改日志,按拦截 ID 放行或调灵敏度。
- 若业务不需要 SVG 上传,保持禁止即可;需要时单独开白名单,别为了省事关掉整类文件检查。
安全插件和别的插件叠在一起时,上传链路更容易出假阳性。插件二分和恢复模式的具体做法,可以对照 插件冲突导致后台上传异常的排查要点,这里不展开重复步骤。
注意:生产环境临时关安全组件要有时间窗口,测完立刻恢复;不要把「先关掉再说」留过夜。
5. 第四层:CDN / 反代缓冲与 body 限制
站前面挂了 Cloudflare、又拍云、阿里云 CDN,或 Nginx 反代时,管理后台的上传请求有时会打到边缘节点,被缓冲或 body 大小限制直接掐断。典型症状:直连源站 IP(改 hosts)能传,走域名就不行;或者 Network 里变成 413 / 502,响应头带 CDN 标识。
常见处理:
- 后台路径(至少
/wp-admin/、async-upload.php)对上传相关请求做「绕过缓存 / 不缓冲」;纯静态加速规则不要套到后台 POST。 - Nginx 反代检查
client_max_body_size(例如client_max_body_size 64m;),以及上游proxy_request_buffering是否把大包拖死。 - CDN 控制台里看是否有「上传文件大小」「Web 应用防火墙」对 POST body 的限制;必要时对源站回源白名单或把后台子域直连源站。
- 改完清边缘缓存后再测,避免旧规则残留。
CDN 和源站 PHP 限制要两边都够,只改一侧经常会出现「偶发成功、偶发失败」。
另外提醒一句:若站点把上传接到了对象存储插件,失败点可能在插件自己的签名或跨域,而不在本地 uploads。先临时切回「本地上传」测一把,能区分是 WordPress/PHP 链路问题,还是远端存储配置问题。
6. 修完后的验收清单
按层动完配置,用同一张「之前失败」的图再传一次,并勾这几项:
- Network 里
async-upload.php为 200,响应是正常 JSON(含附件 ID)。 - 媒体库能看到缩略图,点开原图 URL 可访问(不是 404 / 权限页)。
- 前台文章插入该图可正常显示;若开了对象存储 / CDN,确认回源路径正确。
- 安全插件 / WAF 已恢复开启,日志里没有新的误拦记录。
- 生产改过的 php.ini、Nginx、CDN 规则有备份,出问题能回滚。
上传问题看起来玄,其实大多是限制值、可写路径、安全误杀、边缘拦截四层叠在一起。按上面顺序一次只动一层,通常比反复换主题快。若你想按自己站点的 PHP、插件和 CDN 现状过一遍问题清单,可以看这份 按站点现状出问题清单的免费诊断。