状态码造成微信公众号“该公众号提供的服务出现故障”

举报
AnRFDev 发表于 2021/08/03 21:53:54 2021/08/03
【摘要】 使用NestJS给微信公众号提供后台服务,用户发消息后公众号显示“该公众号提供的服务出现故障”

bug描述

我们使用NestJS写后台代码,给微信公众号提供服务。
用户给公众号发消息时,公众号会显示“该公众号提供的服务出现故障”。
虽然后台代码可以正常处理业务,但这个提示非常影响用户体验。

检查

根据微信公众号文档给的提示,出现这个问题的原因是没有给微信服务器返回正确的信息。

微信服务器需要的是success或者空的字符串。不能是json格式的字符串。
搜了一下其他文章,有的说xml里也不能带有空格;有的说公众号绑定了第三方平台,要去解绑。
但这些和我们的情况不一致。

给公众号的接口是默认返回success的。

查看运行log,发现用户发送1条消息给公众号,我们的服务端会收到4条一模一样的消息。
这4条消息的MsgId是一样的。网上也有人提供了防止重复消息的办法。

于是尝试以下方法

  1. 维护一个map,key是MsgId。
  2. 接收到消息后,如果发现是重复的MsgId,则立刻返回success(或者空字符串)。

但是问题依旧没有解决。

微信服务器认为它没有拿到正确的返回值,于是走了重试的流程。
我们ubuntu服务器上使用了nginx,于是我们查看nginx的log

81.69.1.1 - - [03/Aug/2021:09:41:25 +0800] "POST /mywxserve/?signature=sign1111&timestamp=1627954885&nonce=1832145745&openid=qqq HTTP/1.1" 201 0 "-" "Mozilla/4.0"
81.69.1.1 - - [03/Aug/2021:09:41:26 +0800] "POST /mywxserve/?signature=sign1111&timestamp=1627954885&nonce=1832145745&openid=qqq HTTP/1.1" 201 7 "-" "Mozilla/4.0"
81.69.1.1 - - [03/Aug/2021:09:41:26 +0800] "POST /mywxserve/?signature=sign1111&timestamp=1627954885&nonce=1832145745&openid=qqq HTTP/1.1" 201 7 "-" "Mozilla/4.0"
42.192.1.1 - - [03/Aug/2021:09:41:26 +0800] "POST /mywxserve/?signature=sign1111&timestamp=1627954885&nonce=1832145745&openid=qqq HTTP/1.1" 201 7 "-" "Mozilla/4.0"

可以看到有2个ip地址,发来了3+1次请求。看到nginx返回的状态码都是201。
(ip地址和信息模糊处理)

状态码201表示“已创建”。NestJS默认状态码是200,但是默认POST的状态码是201。

修复

我们强制让nestjs返回状态码200

@HttpCode(200)
@Post()
async onWxEvent(@Body('xml') xmlData: IWxMessageXmlData): Promise<string> {}

再尝试一下,看到nginx的log,返回状态码是200了。公众号也正常了。

81.69.1.1 - - [03/Aug/2021:09:53:27 +0800] "POST /mywxserve/?signature=rustfisher&timestamp=1627955607&nonce=1829147547&openid=xxx0 HTTP/1.1" 200 0 "-" "Mozilla/4.0"

由此可见,接收微信公众号消息的时候,除了要返回空字符串或者success文本;返回状态码必须是200。
用其他的后台框架可能不会遇到状态码问题。

参考

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。