WordPress 媒体库上传图片报「HTTP 错误」:php.ini、临时目录、安全插件和 CDN 怎么逐层查

前天帮一个外贸站排障:媒体库里选一张 800KB 左右的 JPG,点上传,进度条走到一半直接弹「HTTP 错误」。文件不大,格式也正常,换 WebP、PNG 一样挂。后台其他页面都还能用,就是上传这条路不通。

这种报错几乎不带有效信息。WordPress 前端只是告诉你请求失败了,真正原因多半在 PHP 上传限制、临时目录、安全规则,或者 CDN / 反代把 async-upload.php 截掉了。别急着换主题、重装,先把现象钉死,再按层查。

1. 先复现,别猜

打开无痕窗口登录后台,F12 → Network,勾上 Preserve log,再上传一次。重点看 async-upload.php(有的环境会走 admin-ajax.php)这一条:

  1. 状态码:413 / 403 / 500 / 502 指向不同方向;200 但响应体不是预期 JSON,也算失败。
  2. Response 前几行:是 HTML 错误页、WAF 拦截页,还是空的?
  3. 请求大小: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 错误」。

按这个顺序核对:

  1. upload_tmp_dir 是否存在、属主是否是运行 PHP 的用户、权限是否可写(常见 1777 或属主正确的 0755)。
  2. df -h 看根分区和挂载点是不是 100%;inode 满了(df -i)也会写不进去。
  3. open_basedir 是否包含临时目录和 wp-content/uploads;迁站后路径变了最容易漏。
  4. 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 时。

排查时建议:

  1. 先只停用安全类插件(不要一次关光所有插件),再试上传。
  2. 能过之后,逐个打开并收紧规则:给 /wp-admin/async-upload.php、必要的 admin-ajax.php 加例外,而不是整站关防火墙。
  3. 主机面板里看 ModSecurity / 防篡改日志,按拦截 ID 放行或调灵敏度。
  4. 若业务不需要 SVG 上传,保持禁止即可;需要时单独开白名单,别为了省事关掉整类文件检查。

安全插件和别的插件叠在一起时,上传链路更容易出假阳性。插件二分和恢复模式的具体做法,可以对照 插件冲突导致后台上传异常的排查要点,这里不展开重复步骤。

注意:生产环境临时关安全组件要有时间窗口,测完立刻恢复;不要把「先关掉再说」留过夜。

5. 第四层:CDN / 反代缓冲与 body 限制

站前面挂了 Cloudflare、又拍云、阿里云 CDN,或 Nginx 反代时,管理后台的上传请求有时会打到边缘节点,被缓冲或 body 大小限制直接掐断。典型症状:直连源站 IP(改 hosts)能传,走域名就不行;或者 Network 里变成 413 / 502,响应头带 CDN 标识。

常见处理:

  1. 后台路径(至少 /wp-admin/、async-upload.php)对上传相关请求做「绕过缓存 / 不缓冲」;纯静态加速规则不要套到后台 POST。
  2. Nginx 反代检查 client_max_body_size(例如 client_max_body_size 64m;),以及上游 proxy_request_buffering 是否把大包拖死。
  3. CDN 控制台里看是否有「上传文件大小」「Web 应用防火墙」对 POST body 的限制;必要时对源站回源白名单或把后台子域直连源站。
  4. 改完清边缘缓存后再测,避免旧规则残留。

CDN 和源站 PHP 限制要两边都够,只改一侧经常会出现「偶发成功、偶发失败」。

另外提醒一句:若站点把上传接到了对象存储插件,失败点可能在插件自己的签名或跨域,而不在本地 uploads。先临时切回「本地上传」测一把,能区分是 WordPress/PHP 链路问题,还是远端存储配置问题。

6. 修完后的验收清单

按层动完配置,用同一张「之前失败」的图再传一次,并勾这几项:

  1. Network 里 async-upload.php 为 200,响应是正常 JSON(含附件 ID)。
  2. 媒体库能看到缩略图,点开原图 URL 可访问(不是 404 / 权限页)。
  3. 前台文章插入该图可正常显示;若开了对象存储 / CDN,确认回源路径正确。
  4. 安全插件 / WAF 已恢复开启,日志里没有新的误拦记录。
  5. 生产改过的 php.ini、Nginx、CDN 规则有备份,出问题能回滚。

上传问题看起来玄,其实大多是限制值、可写路径、安全误杀、边缘拦截四层叠在一起。按上面顺序一次只动一层,通常比反复换主题快。若你想按自己站点的 PHP、插件和 CDN 现状过一遍问题清单,可以看这份 按站点现状出问题清单的免费诊断。

相关推荐
时间售卖铺1 小时前
MySQL 数据库账户及授权
运维·数据库·mysql·云原生
java_logo1 小时前
Docker 部署 MaxKB:轻松搭建企业级智能体平台
运维·docker·容器·知识库·智能体·maxkb·轩辕镜像
IT大白鼠3 小时前
彭大帅的AI运维助手——怎么给AI写运维SOP:提示词设计实战
运维·人工智能·彭大帅
小白跃升坊7 小时前
PHP2Shell:AI 两天挖出 9.2 分漏洞,让全球 70% 网站连夜打补丁!1Panel 已经把修复版本封装好,推到了你的应用商店里。
php·开源安全·1panel·ai安全·漏洞披露
Json____10 小时前
PHP 突发严重安全漏洞,AI 开始改变网络安全的攻防方式
人工智能·web安全·php·it学习·wwwoop.com
Canmag 兴隆磁性10 小时前
中大型钕铁硼产品的磁通测量与自动分选:一条产线自动化的工程实现思路
运维·学习·自动化·永磁材料
catchadmin10 小时前
PHP 8.7 协程新提案 让跨协程代码共享请求身份
开发语言·php
Web极客码11 小时前
我用 Claude 分析 Redis 哨兵日志,实现跨机房数据不一致自动对齐
数据库·redis·php
xuefeiniao12 小时前
PHP2Shell漏洞修复
运维·服务器·php