今天给壹导航处理用户注册问题时,我碰到一个看起来很普通、实际却相当隐蔽的故障:用户明明只输入了数字,系统却一直提示“此用户名包含无效字符,只能使用字母数字下划线”。更离谱的是,换成纯字母、字母加数字、带下划线的用户名,结果依然完全一样。
我前后检查了主题、子主题、自定义字体、登录跳转代码、缓存和验证码,最后才发现真正的原因不是用户名,也不是 WordPress,而是“禁止的昵称关键词”末尾多了一个英文逗号。
故障现象:正常用户名全部提示无效
最开始测试注册时,我使用的是一个六位纯数字用户名。按页面提示,用户名允许使用字母、数字和下划线,理论上不应该报错,但提交后右下角仍然出现了无效字符提示。

为了避免被单个测试账号误导,我又分别测试了以下几种格式:
- 纯数字:
654321 - 纯字母:
abcde - 字母和数字:
a1234 - 字母、数字和下划线:
abc_123
这几种写法全部返回相同提示,说明问题不是某个字符真的不合法,而是校验流程把所有用户名都拦截了。
我一开始排查了哪些方向
1. 怀疑自定义字体影响输入
网站使用了自定义字体,并且通过 CSS 同时应用到按钮和输入框。我一度怀疑数字在显示时被替换成了特殊字符。但字体只能改变文字的显示效果,不会改变提交给服务器的原始表单值,因此很快排除了这个方向。
2. 检查顶部和底部自定义脚本
站内有用于登录后返回原页面、自动刷新登录状态的 JavaScript。我逐段检查后发现,这些代码只处理 user_login 登录动作和页面跳转,并不修改注册表单中的用户名,也不会参与 PHP 后端校验。
3. 切换父主题和子主题
我又在父主题与子主题之间切换测试,问题依然存在。由此可以判断,故障更接近 OneNav 的公共注册逻辑或某项后台配置,而不是页面样式。
4. 绕过页面,直接请求注册接口
为了彻底排除浏览器、字体和前端脚本,我直接向 WordPress 的 admin-ajax.php 提交与注册表单相同的数据。多个合法用户名都得到下面这段返回:
{"status":2,"msg":"此用户名包含无效字符,只能使用字母数字下划线!"}
这一步非常关键:它证明错误来自服务器端,和浏览器怎么显示输入内容无关。
继续做对照:WordPress 用户系统其实是正常的
接下来,我通过 WordPress 官方用户接口创建了一个临时订阅者。账号创建成功,随后也正常删除。这说明数据库写入、WordPress 用户表以及基础的 sanitize_user() 清洗功能都没有问题。
也就是说,真正出错的是 OneNav 自己注册回调中的额外判断。
定位代码:两个条件共用了一条错误提示
在网站文件中搜索错误提示文字后,我找到了注册处理文件中的判断:
elseif (
! validate_username($username)
|| is_disable_username($username)
) {
// 返回“用户名包含无效字符”
}
validate_username() 是 WordPress 的用户名验证函数,而 is_disable_username() 是主题增加的“禁止昵称关键词”检查。因为两个条件共用同一句提示,所以页面只告诉我“字符无效”,并没有告诉我其实是禁用关键词出了问题。
最终原因:关键词结尾多了一个英文逗号
问题最终出在禁止昵称关键词的设置上。原来的内容结尾多了一个英文逗号,结构类似这样:
admin,administrator,root,管理员,
主题会使用 preg_split() 按逗号、空格和换行拆分关键词。末尾这个多余的英文逗号会再拆出一个空字符串,实际效果相当于:
admin
administrator
root
管理员
空关键词
接着,主题用下面的逻辑逐个检查:
foreach ($disable_reg_keywords as $keyword) {
if (stristr($name, $keyword) || $keyword == $name) {
return true;
}
}
在 PHP 8 中,stristr() 允许使用空字符串作为要查找的内容。任何用户名都“包含”这个空关键词,因此循环永远返回 true,最终表现为所有用户名都不合法。
解决方案一:删除末尾逗号
最直接的修复方法,是进入主题设置中的禁止昵称关键词配置,删除结尾多余的英文逗号、中文逗号、空格和空白行。正确写法例如:
admin,administrator,root,管理员
重点是最后一个关键词后面不要继续添加逗号。
解决方案二:从代码层过滤空关键词
仅修改后台设置可以立即恢复注册,但为了避免以后再次因为空行或逗号触发同样的问题,我把主题中的函数改成了更稳妥的写法:
function is_disable_username($name)
{
$raw_keywords = trim(
(string) io_get_option('user_nickname_stint', '')
);
if ($raw_keywords === '' || $name === '') {
return false;
}
$keywords = preg_split(
'/[,,\s]+/u',
$raw_keywords,
-1,
PREG_SPLIT_NO_EMPTY
);
if (empty($keywords)) {
return false;
}
foreach ($keywords as $keyword) {
$keyword = trim($keyword);
if (
$keyword !== '' &&
stripos($name, $keyword) !== false
) {
return true;
}
}
return false;
}
这里最关键的是 PREG_SPLIT_NO_EMPTY 和 $keyword !== '':前者在拆分时丢弃空项目,后者在匹配前再做一次保险。
如果直接修改的是父主题文件,主题升级后可能被覆盖。建议记录修改位置、提交给主题作者,或在每次升级后检查这一修复是否已经被官方合并。
修复后的验证步骤
- 保存禁止昵称关键词,确认末尾没有逗号或空行。
- 清除 WordPress Redis 对象缓存及 CDN 页面缓存。
- 分别测试纯字母、字母数字和下划线用户名。
- 确认注册流程能够继续进入邮箱验证码或滑动验证阶段。
- 检查真正需要禁止的关键词仍然能够正常拦截。
这次排查给我的提醒
这次故障最容易误导人的地方,是页面提示与真实原因并不完全一致。提示说“字符无效”,实际却是禁用昵称关键词匹配到了一个空字符串。如果只盯着输入框、字体或用户名格式,很容易反复绕圈。
以后遇到类似问题,我会优先做三件事:用多组输入确认规律、绕过前端直接测试接口、搜索错误提示定位后端判断。很多看起来很大的故障,最后可能真的只是一个不起眼的英文逗号。
最终结论:壹导航这次所有用户名都被判定不合法,是因为“禁止的昵称关键词”结尾多了一个英文逗号。删除逗号并过滤空关键词后,注册功能恢复正常。
你认为这个网站怎么样?
-人
-人
-人
-人
-人
© 版权声明
文章版权归作者所有,未经允许请勿转载。
相关文章
暂无评论...