bug描述
我們使用NestJS寫後臺程式碼,給微信公眾號提供服務。
使用者給公眾號發訊息時,公眾號會顯示“該公眾號提供的服務出現故障”。
雖然後臺程式碼可以正常處理業務,但這個提示非常影響使用者體驗。
檢查
根據微信公眾號文件給的提示,出現這個問題的原因是沒有給微信伺服器返回正確的資訊。
微信伺服器需要的是success
或者空的字串。不能是json格式的字串。
搜了一下其他文章,有的說xml裡也不能帶有空格;有的說公眾號繫結了第三方平臺,要去解綁。
但這些和我們的情況不一致。
給公眾號的介面是預設返回success
的。
檢視執行log,發現使用者傳送1條訊息給公眾號,我們的服務端會收到4條一模一樣的訊息。
這4條訊息的MsgId是一樣的。網上也有人提供了防止重複訊息的辦法。
於是嘗試以下方法
- 維護一個map,key是MsgId。
- 接收到訊息後,如果發現是重複的MsgId,則立刻返回
success
(或者空字串)。
但是問題依舊沒有解決。
微信伺服器認為它沒有拿到正確的返回值,於是走了重試的流程。
我們ubuntu伺服器上使用了nginx,於是我們檢視nginx的log
81.69.1.1 - - [03/Aug/2021:09:41:25 +0800] "POST /mywxserve/?signature=sign1111×tamp=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×tamp=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×tamp=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×tamp=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×tamp=1627955607&nonce=1829147547&openid=xxx0 HTTP/1.1" 200 0 "-" "Mozilla/4.0"
由此可見,接收微信公眾號訊息的時候,除了要返回空字串或者success
文字;返回狀態碼必須是200。
用其他的後臺框架可能不會遇到狀態碼問題。