上周帮朋友看一个企业站:文章改了两行字,点「更新」,右下角弹出一句「更新失败。此响应不是合法的 JSON 响应。」刷新再点,还是一样。草稿其实有时候存进去了,有时候没有,最烦人的就是这种半成功。
这个报错本身几乎不带信息量。它真正的意思是:编辑器请求了 /wp-json/wp/v2/posts/ID,拿回来的东西不是 JSON------可能是一个 HTML 错误页、一个 301 跳转、一段 PHP Notice,甚至是 WAF 的拦截页。所以别猜,先看它到底拿回来了什么。

第一步:打开开发者工具,看那一条请求
Chrome 按 F12 → Network,勾上 Preserve log,再点一次「更新」。筛选 wp-json,找到那条 POST(或带 _method=PUT 的请求),看三样东西:
- 状态码:200 / 301 / 403 / 404 / 500 各指向完全不同的方向
- Response 的前几行 :是
{开头,还是<!DOCTYPE html>、Warning:、Notice: - 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 加白名单
修完怎么确认
- 无痕窗口登录后台,新建一篇草稿,写一段带代码块的正文,保存、更新、再发布各点一次
- Network 里那条
wp-json请求返回 200,响应体以{开头 - 浏览器直接访问
/wp-json/wp/v2/posts?per_page=1,能看到 JSON - 看一眼
debug.log,保存时没有新增 Notice / Fatal
朋友那个站最后就是云 WAF 的一条「XSS 防护」规则,把文章里的一段 HTML 示例当成了攻击。在规则里给后台的 /wp-json/wp/v2/ 路径加了例外,五分钟搞定。如果你这边按上面顺序走完还是卡住,可以拿网址做一次 WordPress 站点问题免费诊断,会按问题列个优先级清单,不涉及排名承诺。