搜索全站
主题 12 分钟阅读

WordPress 演示数据导入失败的排查:内存、超时与必需插件缺失

进度条卡在 27%、提示 “The response is not a valid JSON response”、或者干脆 500——本文按“内存/超时/REST 权限/必需插件”四条主线给出排查顺序与可复制的命令行替代方案。

U
UFO_PF 2021-05-20 · 阅读 12 分钟
Wo 主题
阅读提示
本文约 4,768 字,预计阅读 12 分钟。文中命令与配置均经过实测,可直接参考执行。

引言:进度条卡住,然后是一句看不懂的英文

演示数据导入失败的表现形式很多:进度条停在某个百分比不动;弹一句 The response is not a valid JSON response;浏览器直接 500;或者导入显示成功,但媒体全是占位符。

它们背后的原因其实是有限的几类,而且有明确的排查顺序。难点在于错误信息往往指向错误的方向——比如 not a valid JSON response 看起来像是 AJAX 坏了,实际上九成情况是内存不足或进程超时导致 PHP 在中途被杀掉,返回了半截 HTML 错误页,前端解析 JSON 当然失败。

本文按“四条主线”来组织:内存上限、执行时间限制、REST/权限通路、以及缺失的必需插件。按这个顺序走,绝大多数导入问题都能在二十分钟内定位。如果你遇到的不是失败而是“导入了但不像演示站”,请转看为什么导入演示数据后和演示站不一样。

原理分析:导入流程到底经过哪些关卡

一次 Web 方式的演示导入(以 OCDI 为例)是这样的:

  1. 浏览器带着 selected demo index 发一次 AJAX/REST 请求
  2. 服务端下载或读取本地的 XML + JSON 配置文件
  3. 解析 XML(这一步最吃内存:整个 DOM 载入内存)
  4. 逐条 wp_insert_post / wp_insert_attachment 写入数据库
  5. 处理附件下载(要发外部 HTTP 请求,受服务器的出站网络限制)
  6. 返回 JSON 结果给前端

任何一步超过 memory_limit 或 max_execution_time,PHP 就会被杀掉,返回的是错误页而不是 JSON——前端因此报 “not a valid JSON response”。这就是为什么这条错误信息几乎总是假的。

另外两处容易被忽略:第 5 步需要服务器能访问外网(很多国内服务器对外部 CDN 的连通性不稳定),以及 AJAX/REST 需要未被安全插件/防火墙拦截(Wordfence、Cloudflare 的 Bot Fight Mode 都可能拦下管理员自己的导入请求)。

保姆级实操

第一步:先把真实错误挖出来。

// wp-config.php —— 临时开启调试(排查结束后务必关掉)
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );
@ini_set( 'display_errors', 0 );
# 导入过程中实时盯日志
tail -f wp-content/debug.log
# 若没有该文件,看 PHP-FPM/Apache 的错误日志
tail -f /var/log/php-fpm/www-error.log 2>/dev/null

日志里若出现 Allowed memory size of X bytes exhausted,就是内存问题;出现 Maximum execution time of 30 seconds exceeded,就是超时。

第二步:抬高 PHP 限制。

// wp-config.php —— 放在 ABSPATH 定义之后
define( 'WP_MEMORY_LIMIT', '512M' );
define( 'WP_MAX_MEMORY_LIMIT', '512M' );
@ini_set( 'memory_limit', '512M' );
@set_time_limit( 300 );

注意:WP_MEMORY_LIMIT 只对 WordPress 上下文有效,WP_MAX_MEMORY_LIMIT 用于 admin 侧。若主机面板限制了 PHP 池的上限,还需要在 php.ini 或 PHP-FPM pool 配置里放开。

; php.ini / www.conf
memory_limit = 512M
max_execution_time = 300
upload_max_filesize = 64M
post_max_size = 64M
max_input_vars = 5000

Nginx 用户还要确认代理层的超时不小于 PHP 侧:

location ~ \.php$ {
    fastcgi_read_timeout 300;
    fastcgi_send_timeout 300;
    client_max_body_size 64m;
}

第三步:确认必需插件已安装并激活。

这是被低估的一步。多数主题的 demo 内容包含构建器(Elementor/WPBakery/Gutenberg 自定义区块)的标记,缺插件时导入过程会在 wp_insert_post 后处理 meta 时出问题,或直接跳过内容。

wp plugin list --status=active --fields=name,version --format=table
grep -rn "tgmpa_register" wp-content/themes/当前主题/ -l | head -2

对照主题文档里的 Required Plugins 清单逐个核对。顺序很重要:先装齐插件,再导入。

第四步:绕开 Web 界面,用命令行导入。

这是最有效的一招——命令行不受 max_execution_time 的浏览器等待限制,也不受安全插件的 AJAX 拦截。

# 安装官方导入器
wp plugin install wordpress-importer --activate

# 导入 WXR(若主题的 demo 包里提供了 XML)
wp import wp-content/plugins/主题/languages/../demo/demo-content.xml --authors=create --skip=image-resize

很多商业主题把 demo XML 放在安装包(demo-content/ 或 sample-data/ 目录)里:

find wp-content/themes/当前主题 -name "*.xml" -o -name "*.wxr" | head

没有 XML 的主题通常依赖其自建导入器,这类情况就得修好 Web 通路。

第五步:修好 REST/AJAX 通路(针对 not a valid JSON response)。

# 1) 检查 REST 是否可达
curl -s -o /dev/null -w "%{http_code}\n" https://example.com/wp-json/wp/v2/posts
curl -s -o /dev/null -w "%{http_code}\n" https://example.com/wp-admin/admin-ajax.php

# 2) 检查是否被主题/htaccess 重定向
curl -sIL https://example.com/wp-json/wp/v2/ | grep -i "^HTTP\|^location"

# 3) 确认固定链接结构不是 "朴素"(朴素模式下 REST 常常异常)
wp option get permalink_structure

常见修复:把固定链接改为 /%postname%/,临时停用安全插件(Wordfence 的 Firewall、登录保护),以及关闭 CDN 的 Bot Fight Mode。Cloudflare 用户可临时对 wp-admin/admin-ajax.php 停用托管挑战规则。

第六步:附件下载失败的单独处理。

如果导入成功但图片全空:

# 1) 检查服务器出站连通性
curl -sI -o /dev/null -w "%{http_code}\n" https://demo.主题官网.com/wp-content/uploads/xxx.jpg

# 2) 若被防火墙拦截,改用手动方式:取出 Attachments XML,本地重新关联
wp media regenerate --yes --skip-delete
wp db query "SELECT COUNT(*) FROM wp_posts WHERE post_type='attachment' AND guid LIKE '%placeholder%';"

第七步:失败后先清干净再重试。

# 半途而废的导入会留下垃圾数据,重来之前清理
wp site empty --yes
wp transient delete --all
wp cache flush
# 导入前把所有内容重置(含媒体)
wp post delete $(wp post list --post_type=attachment --format=ids) --force

常见踩坑

  1. 看到 not a valid JSON response 就去查 JSON。它几乎总是资源限制(内存/超时)造成的半截响应。
  2. 只改 wp-config.php 不改 php.ini。很多主机的 PHP 池 Hard Limit 更低,WP_MEMORY_LIMIT 无效。
  3. 改了 PHP 超时忘了改 Nginx/Apache。代理层 60 秒就断,前面改到 300 也白搭。
  4. 没装必需插件就导入。内容能进去但 meta/字段名对不上,表现为“导入了但页面是空的”。
  5. 开着 Wordfence/Cloudflare Bot Fight 模式。它们会把管理员自己的 AJAX 请求判定为机器人。
  6. 固定链接是“朴素”模式。REST 与 AJAX 在部分主机上会失效。
  7. 案例:某主机声称 memory_limit 已是 512M,导入仍在第 30% 崩。日志显示 Allowed memory size of 134217728 bytes exhausted(128M)——原因是 WordPress 的 WP_MEMORY_LIMIT 没设,实际取的是 PHP 池的值,而面板显示的是“另一个环境的配置”。最终在 wp-config.php 里显式定义 WP_MEMORY_LIMIT 为 512M 才通过。教训:不要相信主机的宣传参数,用 wp eval "echo WP_MEMORY_LIMIT;" 或 phpinfo 亲自验证。

总结

固定排查顺序(内容之外的菜单/首页/配色缺失,请对照为什么导入演示数据后和演示站不一样补齐):开 debug.log 拿真实报错 → 抬 memory_limit 与 max_execution_time(PHP + Nginx 双层)→ 装齐必需插件 → 改用 wp import 命令行绕开 Web → 校验 REST/admin-ajax 通路与固定链接 → 清理半途残留后重试。

三条判断经验:出现 JSON 报错先看日志而不是查代码;附件全空优先查出站网络;反复失败就用 CLI——绕开浏览器和 HTTP 层之后,绝大多数问题都会自然消失。最后记得排查完把 WP_DEBUG 关掉,别把调试日志留在生产环境。

U
UFO_PF作者

专注 WordPress 生态的实战作者,内容以「可复制、可验证」为第一原则。

留下你的想法

邮箱地址不会被公开。带 * 的为必填项。