微信公号调试遇到Nginx错误499 | Nginx Code 499 on Wechat OAuth debugging
最近弄了个公号测试号,尝试一下腾讯OAuth,用的还是习惯的nginx+uwsgi+flask
注意【开放平台】和【公众平台】的OAuth有差别,跳转的auth地址,及scope都是不同的;前者主要用于浏览器app(微信内置浏览器也可兼容),后者跟公众号绑定的更紧密(不关注不能auth)
这货调试蛮坑的 –
- 首先得有公网IP,这个简单,买个按小时付费的美团云(阿里云)就行,1核1G,不要数据盘,带宽1M;一个小时0.1元多一点,一天也不到3块钱,不需要了随时可删。
- (带备案)域名一个。这个有点难度,买云主机备案不要钱,但两周时间等的着实有点心焦。如果有现成域名,可以开个二级域名(端口依然要80),nginx转发一下,这样也是ok的。
木有用域名的时候,我尝试直接用云主机ip接测试号,一共有3处配置,都配了IP(而非域名)
- 接口配置信息
- JS安全域名
- OAuth授权回调域名(关键)
但实际在微信浏览器中访问时,页面无法正常展示,这个提示很关键(转换成手机预览模式)
于是在OAuth的过程中,uwsgi经常报如下错误(而且还是在auth成功之后):
500ms的请求不算慢啊,为啥会broken pipe呢?
并且明显uwsgi返回了code 200,请求没啥问题噻?
1 2 3 4 |
<span style="color: #008000;">Wed Jan 25 16:54:43 2017 - SIGPIPE: writing to a closed pipe/socket/fd (probably the client disconnected) on request /qrScanToTemplateMsg/6?code=0515JtlQ11sLo61riTnQ15CxlQ15Jtl1&state=1 (ip 103.37.140.18) !!! Wed Jan 25 16:54:43 2017 - uwsgi_response_writev_headers_and_body_do(): Broken pipe [core/writer.c line 296] during GET /qrScanToTemplateMsg/6?code=0515JtlQ11sLo61riTnQ15CxlQ15Jtl1&state=1 (103.37.140.18) IOError: write error [pid: 24226|app: 0|req: 11/19] 103.37.140.18 () {38 vars in 892 bytes} [Wed Jan 25 16:54:42 2017] GET /qrScanToTemplateMsg/6?code=0515JtlQ11sLo61riTnQ15CxlQ15Jtl1&state=1 => generated 0 bytes in 468 msecs (HTTP/1.1 200) 3 headers in 0 bytes (0 switches on core 0)</span> |
开始时,丈二和尚摸不着头脑,鉴于uwsgi是nginx的upstream,那就找一下nginx看人家说啥呗
一看不要紧,同一个请求,nginx code是499;google后,表明499是“客户端主动关闭连接”,那么uwsgi送给nginx的200自然木有什么卵用了 – 客户端不要了
而且这一条log是在access.log而非error.log,说明nginx并木有怪罪uwsgi
1 |
<span style="color: #008000;">103.37.140.18 - - [25/Jan/2017:16:54:43 +0800] "GET /qrScanToTemplateMsg/6?code=0515JtlQ11sLo61riTnQ15CxlQ15Jtl1&state=1 HTTP/1.1" 499 0 "-" "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 6P Build/MTC20L) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/37.0.0.0 Mobile MQQBrowser/6.9 TBS/036903 Safari/537.36 MicroMessenger/6.5.3.980 NetType/WIFI Language/zh_CN" "-"</span> |
who to blame right now?
我开始怀疑没有域名导致的转码,找了一个备案后没用过的域名,指向这个ip,不到一分钟就生效了
然后把测试号那三处配置都改成域名,再试。。。搞定了,同一个链接,uwsgi和nginx log都是code 200.
1 |
<span style="color: #008000;">123.151.38.94 - - [25/Jan/2017:21:17:02 +0800] "GET /qrScanToTemplateMsg/6?code=0011MCQf1s8UTv0ZMHTf1CcRQf11MCQ3&state=1 HTTP/1.1" 200 480 "-" "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 6P Build/MTC20L) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/37.0.0.0 Mobile MQQBrowser/6.9 TBS/036903 Safari/537.36 MicroMessenger/6.5.3.980 NetType/WIFI Language/zh_CN" "120.221.74.188"</span> |
同时网页访问也展示正常了,不需要什么“转换成手机预览模式”(截图就不贴了)。
究其本质,这个nginx code# 499(以及uwsgi的broken pipe),也即客户端主动断开连接,就是ip访问状态下,微信浏览器为了安全防护,拒绝直接渲染前端页面造成的。
文章的脚注信息由WordPress的wp-posturl插件自动生成