周四晚上下班后,我群群友 @Tsri Gero 和我反馈了一个问题。他表示只要用 QQ 浏览器访问他的博客,就会提示出现 500 错误(Database Query Error)即数据库执行错误。

分析过程

我首先让他在博客程序根目录下的 config.inc.php 里添加一段代码,开启 Typecho 的 Debug 排错模式,方便定位错误信息。

define('__TYPECHO_DEBUG__', true);

通过查看该报错信息后发现,其实是因为他使用的 Access 插件创建的 access_log 表里面一个名为 ua 的字段出现了问题,报错信息为 Data too long for column 'ua',即插入到 ua 字段的内容太长了。

于是我就去分析了一下 QQ 浏览器的 UA 信息,我的 奇趣播放器 文档页面本身就有一个显示浏览器 UA 的位置,当初是为了测试兼容性加上去的,至今没有删除。我将页面输出的 UA 信息复制,粘贴到我的数据库里面去执行,果然这个问题也成功复现了。

执行语句错误

这个是 QQ 浏览器的 UA:

Mozilla/5.0 (Linux; Android 8.1.0; 16th Build/OPM1.171019.026; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/66.0.3359.126 MQQBrowser/6.2 TBS/045104 Mobile Safari/537.36 V1_AND_SQ_8.2.0_1296_YYB_D QQ/8.2.0.4310 NetType/WIFI WebP/0.3.0 Pixel/1080 StatusBarHeight/84 SimpleUISwitch/0

而这个是我使用 Chrome 浏览器得到的 UA 信息,比腾讯家的都少了很多,自然存进去不会报错。

Mozilla/5.0 (Linux; Android 8.1.0; 16th) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.96 Mobile Safari/537.36

还记得前段时间我写的《2019 年度总结》吗,我的班主任通过我发的朋友圈点进去看了,她想参与评论却得到了服务器的 500 信息,那时候我也郁闷不解。现在确认发现了这个问题之后,我在想会不会微信也一并出现了这样的问题?

班主任评论失败

经过测试后发现,微信的 UA 信息和 QQ 差不多,甚至比它还要长!

Mozilla/5.0 (Linux; Android 8.1.0; 16th Build/OPM1.171019.026; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/67.0.3396.87 XWEB/1162 MMWEBSDK/191201 Mobile Safari/537.36 MMWEBID/275 MicroMessenger/7.0.10.1580(0x27000A55) Process/tools NetType/WIFI Language/zh_CN ABI/arm64

由于我班主任是在评论出现这个问题的,于是我去看了下自己 Typecho 的评论表 comments,可以看到它确实存储了评论者的 UA 信息,它是用 varchar(255) 存储的,和前面 Access 插件类似。我用自己的手机在微信里进行评论,也确实复现了。

微信复现

解决方法

那么基本上可以确定这个问题了,要解决它只需要更改一下字段的存储大小。如果你使用了 Access 插件,也建议一并扩大相关字段。

扩大评论的 UA 字段(将 paul 替换为你的前缀)

ALTER TABLE `paul_comments` CHANGE `agent` `agent` VARCHAR(512)

扩大 Access 插件的 UA 字段(将 paul 替换为你的前缀)

ALTER TABLE `paul_access_log` CHANGE `ua` `ua` VARCHAR(512)

当然,你也可以直接明令禁止使用 QQ 浏览器访问,毕竟这个浏览器无论是性能还是优化都不及于 Chrome,一刀切也不是不行。

参与修复

看了下 Typecho 仓库的最新版本,貌似评论表的这个问题已经被解决。仅限使用最新 Release(17.10.30)或早期部署安装 Typecho 的博客可能出现这个问题(我博客在几年前就开始用了)。而同时出现问题的 Access 插件我将会反馈给作者,并提个 Pull Request 给予改善。