WordPress 古腾堡点「更新」报「不是有效的 JSON 响应」:我按 REST 接口一路查下来的顺序

上周帮朋友看一个企业站:文章改了两行字,点「更新」,右下角弹出一句「更新失败。此响应不是合法的 JSON 响应。」刷新再点,还是一样。草稿其实有时候存进去了,有时候没有,最烦人的就是这种半成功。

这个报错本身几乎不带信息量。它真正的意思是:编辑器请求了 /wp-json/wp/v2/posts/ID,拿回来的东西不是 JSON------可能是一个 HTML 错误页、一个 301 跳转、一段 PHP Notice,甚至是 WAF 的拦截页。所以别猜,先看它到底拿回来了什么。

第一步:打开开发者工具,看那一条请求

Chrome 按 F12 → Network,勾上 Preserve log,再点一次「更新」。筛选 wp-json,找到那条 POST(或带 _method=PUT 的请求),看三样东西:

  1. 状态码:200 / 301 / 403 / 404 / 500 各指向完全不同的方向
  2. Response 的前几行 :是 { 开头,还是 <!DOCTYPE html>、Warning:、Notice:
  3. Request URL 的协议和域名:是不是 http 和 https 混着用,或者请求去了另一个域名

我那次看到的是 403,响应体是一段带云厂商 logo 的 HTML------答案已经出来一半了。

按状态码分流

403:大概率是安全层拦了

  • 服务器或 CDN 的 WAF 规则,把正文里出现的 <script>、iframe、SQL 关键词当成攻击(写技术文章、贴代码的站特别容易中)
  • 安全插件(防火墙类)开了「禁用 REST API」或只允许登录用户但 nonce 校验不过
  • 宝塔之类面板的「防跨站 / 防火墙」模块

验证方法很直接:把正文里那段代码块先剪掉再保存。能存,就是内容触发了规则,去 WAF 里给 /wp-json/ 加白名单或调规则,而不是关掉整个防火墙。

404:REST 路由压根没走到 WordPress

访问 https://你的域名/wp-json/,正常会返回一大段 JSON。如果是 404,基本是伪静态没生效------Nginx 少了 try_files $uri $uri/ /index.php?$args;,或者 Apache 的 .htaccess 没被读取。临时验证可以访问 https://你的域名/?rest_route=/,这个能通就坐实了是 rewrite 的问题。

301 / 302:地址不一致

后台「设置 → 常规」里的 WordPress 地址和站点地址,一个是 http、一个是 https,或者一个带 www 一个不带。编辑器按其中一个发请求,服务器又把它跳到另一个,POST 跳转之后很多情况下就变成 GET 或者直接丢了请求体。

两个地址统一成最终访问的那一个,wp-config.php 里如果写死了 WP_HOME / WP_SITEURL 也一起对一下。走了 CDN 或反代、源站其实是 http 的,记得让 WordPress 识别 X-Forwarded-Proto,否则它会一直以为自己在 http 下。

200 但不是 JSON:输出被污染了

这类最隐蔽。响应体开头多了一行 Deprecated: ... 或者一个空行、一个 BOM,JSON 解析就失败。常见来源:

  • wp-config.php 里 WP_DEBUG_DISPLAY 开着,PHP 升级后旧插件疯狂报 Deprecated
  • 某个主题 functions.php 末尾多了 ?> 后面跟着空行
  • 文件被编辑器存成了「UTF-8 with BOM」

处理:生产环境把 WP_DEBUG_DISPLAY 设为 false,日志写到 debug.log 里看;再挨个查最近改过的 PHP 文件开头结尾。

500:后端直接崩了

看 wp-content/debug.log 或 PHP-FPM 错误日志,通常是某个插件在 save_post 钩子里出了 Fatal。这时候按插件冲突的思路走,停用到只剩一个再逐个打开。插件二分和恢复模式的具体做法,我之前整理过一份 WordPress 插件冲突排查步骤,这里不重复。

几个我见过但容易被忽略的情况

  • 永久链接设成了「朴素」:老版本里个别环境下 REST 走不通,换成「文章名」再保存一次
  • 服务器限制了 PUT/DELETE :有些老虚拟主机只放行 GET/POST,编辑器会自动降级,但中间如果还有一层反代把 X-HTTP-Method-Override 头剥掉了,就会失败
  • 上传大图后保存失败 :其实是 post_max_size / Nginx 的 client_max_body_size 太小,返回的是 413 的 HTML 页
  • 换完 SSL 证书当天出问题:混合内容不会直接导致这个报错,但地址设置没跟着改就会触发上面的 301 情况

别做的事

  • 别装「经典编辑器」插件当解决方案。它绕开了 REST,看起来好了,但 REST 坏着,很多插件、小程序接口、Headless 前端照样会出问题
  • 别为了省事把 REST API 整个关掉,WordPress 后台本身就依赖它
  • 别在正式站直接关 WAF 测试,先在预发环境或者给自己 IP 加白名单

修完怎么确认

  1. 无痕窗口登录后台,新建一篇草稿,写一段带代码块的正文,保存、更新、再发布各点一次
  2. Network 里那条 wp-json 请求返回 200,响应体以 { 开头
  3. 浏览器直接访问 /wp-json/wp/v2/posts?per_page=1,能看到 JSON
  4. 看一眼 debug.log,保存时没有新增 Notice / Fatal

朋友那个站最后就是云 WAF 的一条「XSS 防护」规则,把文章里的一段 HTML 示例当成了攻击。在规则里给后台的 /wp-json/wp/v2/ 路径加了例外,五分钟搞定。如果你这边按上面顺序走完还是卡住,可以拿网址做一次 WordPress 站点问题免费诊断,会按问题列个优先级清单,不涉及排名承诺。

相关推荐
行思理3 小时前
个推厂商应用开通指南
运维·服务器·uni-app·个推·uni-app push
龙亘川3 小时前
电子印章系统对接管理业务建模:从需求申请、接口开发到监控运维的全流程闭环
大数据·运维·人工智能·智慧城市·开源软件
研发小能3 小时前
DevOps 国产替代选型指南:从“单点替换“到“一体化平台“
运维·研发效能·devops·嘉为蓝鲸
l1t4 小时前
DeepSeek总结的本地优先的分析不需要数据库服务器
运维·服务器·数据库·人工智能·duckdb
专业程序开发源4 小时前
springboot校企合作双选会一站式预约与面试系统16010-计算机课程设计、毕业设计
java·vue.js·spring boot·后端·面试·php·课程设计
你看我名字4 小时前
LNMP 生产架构与云运维实践:Nginx、PHP-FPM、MySQL 全链路分析
运维·nginx·架构
天远Date Lab4 小时前
零信任架构实战:基于天远车辆估值构建自动化品牌二手车置换智能定价与补贴测算网关
运维·人工智能·架构·自动化
郑州光合科技余经理5 小时前
同城商城源码:商品库和订单库怎么随包交付
android·java·开发语言·后端·uni-app·php·ai编程
flytalei5 小时前
从 Jenkins 到 Argo CD:搭建一条完整的 GitOps 实战链路
运维·jenkins