在接入微信小程序文本内容安全识别时,遇到了 json_encode 默认的 Unicode 编码问题,这个隐含的处理导致请求 msgSecCheck 接口一直响应检测通过,修复办法为增加 JSON_UNESCAPED_UNICODE 参数。

做微信小程序开发,但凡有一点 UGC 内容,那肯定逃脱不了做内容安全检查的工作。如果你没有足够强大和及时的词库,那就乖乖地按微信官方文档接入其 msgSecCheck、mediaCheckAsync 接口,文档地址如下:

小程序安全 /内容安全

我使用的后端系统是 PHP 开发的,在接入 msgSecCheck 接口时发现无论我发送什么内容,接口返回的 label 都是 100(正常)。我搜索了下微信开放社区里相关讨论,发现有不少人都遇到了和我一样的问题:即 msgSecCheck 接口似乎并没有生效,总是返回检查通过,有不少人怀疑这个接口就是用于应付的摆设。以往的经验告诉我,事情肯定不会这么简单,既然这个接口公开在那里这么长时间了,接口本身出问题的概率几乎没有,几乎可以确定就是开发者的接入姿势不对。

我在追行排查后,最终定位发生错误的原因为 JSON 编码参数时使用了:

$json = json_encode($data);

json_encode 使用 UTF-8 编码字符串,但默认会将中文转码为 Unicode 代码点的形式。这种编码方式确保了 JSON 字符串在任何编码环境下都能被正确解析,但会导致中文等字符在查看时不够直观。可以通过增加 JSON_UNESCAPED_UNICODE 参数来防止非 ASCII 字符被转义,而是直接以原始字符形式输出。

一个示例,更直观地对比:

$data = ['name' => '看川博客', 'url' => 'https://kanchuan.com'];
$json = json_encode($data, JSON_UNESCAPED_UNICODE);
var_dump($json);
$json = json_encode($data);
var_dump($json);

打印结果为:

string(54) "{"name":"看川博客","url":"https:\/\/kanchuan.com"}"
string(66) "{"name":"\u770b\u5ddd\u535a\u5ba2","url":"https:\/\/kanchuan.com"}"

修改为:

$json = json_encode($data, JSON_UNESCAPED_UNICODE);

即可满足 msgSecCheck 接口要求。

另外,关于微信 msgSecCheck 接口的测试,有时候我们不太好确定一个词汇在 msgSecCheck 看来是不是有问题,即无法区分 msgSecCheck 接口的返回是真的通过还是接入有问题,我们可以进入微信小程序的后台,依次打开「开发与服务」-「开发管理」-「安全中心」-「内容风控」添加自定义的关键字。对于自定义的关键字,msgSecCheck 的响应是可以确定的,只要我们测试自定义关键字时 msgSecCheck 接口的响应符合预期,即说明接入正确。