今天前端遇到了一个bug,小程序使用split截取字符串的时候,发送到api之后出现错误,查看thinkPHP的日志之后发现param参数是空的。。。然后http抓包发现post请求是有数据的。没办法,只能提取请求数据,设置断点,单步调试。最后发现http请求方式是content-type:application/json,这种方式过来之后的数据源本身是json格式的字符串类型,但是thinkPHP会自动json_decode,解析之后的结果是null。使用json_last_error得到错误编号是JSON_ERROR_UTF16
JSON_ERROR_UTF16 畸形的 UTF-16 字符,可能因为字符编码不正确。 PHP 7.0.0
继续检查http请求数据body,发现有一个 \uxxxx 格式的ASCII单字节,这个字节是不正确的utf-8或者utf-16编码,这个规范写在RFC7159上
不同的编程语言解析json的实现方式不同,PHP 的 json_decode 是符合 RFC 标准的。
经过前端排查,发现使用 JavaScript 的截取字符串函数 split 没法正确截取微信表情格式编码的字符串,可能会出现多余的 ASCII 字节。
最后商量的结果是暂时使用正则表达式过滤掉单个 ASCII 字节码:
$data = json_decode(preg_replace('~\\\u[a-d0-9]{4}~iu',"",\think\facade\Request::getInput()), true);
网友评论