-
Notifications
You must be signed in to change notification settings - Fork 0
/
wechat-multiple-requst.html
450 lines (276 loc) · 14.3 KB
/
wechat-multiple-requst.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
<!doctype html>
<html class="no-js" lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>
微信的坑-微信服务器重发页面请求的问题 - CodingRoad-编程之路
</title>
<link href="atom.xml" rel="alternate" title="CodingRoad-编程之路" type="application/atom+xml">
<link rel="stylesheet" href="asset/css/foundation.min.css" />
<link rel="stylesheet" href="asset/css/docs.css" />
<script src="asset/js/vendor/modernizr.js"></script>
<script src="asset/js/vendor/jquery.js"></script>
<script src="asset/highlightjs/highlight.pack.js"></script>
<link href="asset/highlightjs/styles/github.css" media="screen, projection" rel="stylesheet" type="text/css">
<script>hljs.initHighlightingOnLoad();</script>
<script type="text/javascript">
function before_search(){
var searchVal = 'site:blog.codingroad.com ' + document.getElementById('search_input').value;
document.getElementById('search_q').value = searchVal;
return true;
}
</script>
</head>
<body class="antialiased hide-extras">
<div class="marketing off-canvas-wrap" data-offcanvas>
<div class="inner-wrap">
<nav class="top-bar docs-bar hide-for-small" data-topbar>
<section class="top-bar-section">
<div class="row">
<div style="position: relative;width:100%;"><div style="position: absolute; width:100%;">
<ul id="main-menu" class="left">
<li id=""><a target="_self" href="archives.html">Home</a></li>
<li id=""><a target="_self" href="why_i_write_effecitve_python_notes.html">EffectivePython读书笔记</a></li>
<li id=""><a target="_self" href="about.html">关于</a></li>
</ul>
<ul class="right" id="search-wrap">
<li>
<form target="_blank" onsubmit="return before_search();" action="http://google.com/search" method="get">
<input type="hidden" id="search_q" name="q" value="" />
<input tabindex="1" type="search" id="search_input" placeholder="Search"/>
</form>
</li>
</ul>
</div></div>
</div>
</section>
</nav>
<nav class="tab-bar show-for-small">
<a href="javascript:void(0)" class="left-off-canvas-toggle menu-icon">
<span> CodingRoad-编程之路</span>
</a>
</nav>
<aside class="left-off-canvas-menu">
<ul class="off-canvas-list">
<li><a target="_self" href="archives.html">Home</a></li>
<li><a target="_self" href="why_i_write_effecitve_python_notes.html">EffectivePython读书笔记</a></li>
<li><a target="_self" href="about.html">关于</a></li>
<li><label>Categories</label></li>
<li><a href="mac.html">mac</a></li>
<li><a href="python.html">python</a></li>
<li><a href="java.html">java</a></li>
<li><a href="operation-and-maintenance.html">运维</a></li>
</ul>
</aside>
<a class="exit-off-canvas" href="#"></a>
<section id="main-content" role="main" class="scroll-container">
<script type="text/javascript">
$(function(){
$('#menu_item_index').addClass('is_active');
});
</script>
<div class="row">
<div class="large-8 medium-8 columns">
<div class="markdown-body article-wrap">
<div class="article">
<h1>微信的坑-微信服务器重发页面请求的问题</h1>
<div class="read-more clearfix">
<span class="date">2017/7/30</span>
<span>posted in </span>
<span class="posted-in"><a href='operation-and-maintenance.html'>运维</a></span>
<span class="comments">
</span>
</div>
</div><!-- article -->
<div class="article-content">
<ul>
<li>
<a href="#toc_0">现象</a>
</li>
<li>
<a href="#toc_1">问题定位</a>
<ul>
<li>
<a href="#toc_2">定位思路:</a>
</li>
<li>
<a href="#toc_3">定位过程</a>
</li>
</ul>
</li>
<li>
<a href="#toc_4">问题分析</a>
</li>
<li>
<a href="#toc_5">问题处理</a>
</li>
</ul>
<p>这是一个大坑,可能有人还没有注意到这个问题,但它确实存在,而且可能会影响你的统计数据。</p>
<span id="more"></span><!-- more -->
<h2 id="toc_0">现象</h2>
<p>近期我们在微信上做推广后,做数据分析时发现一些异常数据:</p>
<ul>
<li>大量用户来自天津、上海的ip</li>
<li>这些用户每次只访问一个页面,产生session之后就再也不来了</li>
</ul>
<p>最初我们认为是下游推广渠道在坑我们钱,用天津和上海的服务器来刷访问用户数,近而骗取我们的推广费用。</p>
<p>然而和多家合作方推广后都发现同样的问题,所以觉得这个事情并有这么简单。经过一系列的排查之后才发现,这个大坑居然是微信造成的。</p>
<h2 id="toc_1">问题定位</h2>
<p>为了确认这些“用户”是真用户,还是假用户,我们尝试了大量手段来分析,此处省略5000字,Fuck!</p>
<p>最终我们联想到了UC浏览器预读功能,开始怀疑是某个地方的预读导致,于是按这个思路来进行定位。</p>
<blockquote>
<p>关于UC浏览器的预读功能:开启此功能后,在读小说时,浏览器会分析页面中的“下一章”链接,并后台提前请求服务端拿到响应数据,等用户点下一章的时候,页面就可以瞬间展示出来。</p>
</blockquote>
<h3 id="toc_2">定位思路:</h3>
<ul>
<li>组装一个没有人会访问的URL</li>
<li>通过微信浏览器访问该URL</li>
<li>监控服务端日志,确认是否会有其它人发起同样的请求,如果有,那就说明微信或者中间的网络服务商有人在预读。</li>
</ul>
<h3 id="toc_3">定位过程</h3>
<ol>
<li><p>组装一个没有人会访问的URL</p>
<ul>
<li>正常的URL:/bookinfo/148161271068074.html</li>
<li>组装的URL:/bookinfo/148161271068074.html?c=fuckwx</li>
</ul>
<blockquote>
<p>说明一下:为了验证这个问题,我们另外搭了一个服务器,根本不会有用户访问。而且这个世界上应该没有人会同时带fuckwx这个参数来访问我的服务器。</p>
</blockquote></li>
<li><p>微信浏览器访问</p></li>
<li><p>监控服务端accesslog</p>
<pre><code class="language-shell">wap@iZ2zeg0900kzwn7hnqg3pzZ:~/app/apache-tomcat-7.0.68/logs$ tailf localhost_access_log.2017-05-17.txt | grep fuckwx
20170517172145|045|112.17.238.22|2833|GET|/bookinfo/148161271068074.html|200|19|?c=fuckwx|Mozilla/5.0 (iPhone; CPU iPhone OS 8_1_2 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Mobile/12B440 MicroMessenger/6.5.3 NetType/4G Language/zh_CN
20170517172154|054|117.185.27.114|2832|GET|/bookinfo/148161271068074.html|200|8|?c=fuckwx|Mozilla/5.0 (iPhone; CPU iPhone OS 10_2_1 like Mac OS X) AppleWebKit/602.4.6 (KHTML, like Gecko) Mobile/14D27 MicroMessenger/6.5.5 NetType/WIFI Language/zh_CN
</code></pre>
<p><strong>到这里已经基本可以确认,就是有人在重发我的请求</strong><br/>
我的ip是 <code>112.17.238.22</code> 浙江移动的IP。<br/>
而这个重发的ip是 <code>117.185.27.114</code> 上海移动的IP。</p></li>
<li><p>为了确认是微信的问题,还是中间网络服务端的问题。我们通过更换浏览器,更换网络环境进行对比测试,结果发现:只有在微信浏览器下会出现这个问题,与网络环境无关。</p></li>
<li><p>抓包信息http头结果如下:</p>
<ul>
<li><p>真实用户请求<br/>
<img src="media/14950134973267/14950155228633.jpg" alt=""/></p></li>
<li><p>微信服务器请求</p></li>
</ul>
<p><img src="media/14950134973267/14950156475859.jpg" alt=""/> </p></li>
</ol>
<h2 id="toc_4">问题分析</h2>
<p>通过上述的数据我们发现以下问题<br/>
1. 微信是在真实用户请求后几秒内,接着发起一次同样地址的请求。<br/>
2. 微信在请求的时候更换了UA。<br/>
3. 微信在请求的时候没有携带cookie。<br/>
4. 微信是完全随机IP进行访问,目前来看应该是有好几个段的IP在做这个事情,主要集中在天津和上海。<br/>
5. 微信是完全随机进行这样的重发操作,找不到任何规律。</p>
<p>这些特性放在一起,就很尴尬了啊:<strong>服务端完全不知道这个请求是机器人还是真实用户</strong>,我们统计出来的访问用户数就明显不准确了,而且会影响人均PV等统计数据。</p>
<h2 id="toc_5">问题处理</h2>
<p>暂时想到的是通过js来埋点的方式进行用户统计,但是需要验证这个微信是否会对ajax请求做同样的重发操作。</p>
<p>其它方案还是没有想到:</p>
<p>如果有哪位读者想到了求分享思路。</p>
<p>同时如果有微信内部的人看到了这个文章,麻烦解惑一下微信这么做的原因。以及我们的应对方案。</p>
</div>
<div class="row">
<div class="large-6 columns">
<p class="text-left" style="padding:15px 0px;">
<a href="zhejiang-cmcc-http-status-hijacking.html"
title="Previous Post: 浙江移动劫持404、500等响应码问题处理">« 浙江移动劫持404、500等响应码问题处理</a>
</p>
</div>
<div class="large-6 columns">
<p class="text-right" style="padding:15px 0px;">
<a href="use-docker-deploy-zabbix.html"
title="Next Post: Docker安装zabbix-server">Docker安装zabbix-server »</a>
</p>
</div>
</div>
<div class="comments-wrap">
<div class="share-comments">
</div>
</div>
</div><!-- article-wrap -->
</div><!-- large 8 -->
<div class="large-4 medium-4 columns">
<div class="hide-for-small">
<div id="sidebar" class="sidebar">
<div id="site-info" class="site-info">
<div class="site-a-logo"><img src="media/15329222251882/codingroad-logo.png" /></div>
<h1>CodingRoad-编程之路</h1>
<div class="site-des"></div>
<div class="social">
<a target="_blank" class="google" href="https://plus.google.com/u/0/107554665621156148465" rel="author" title="Google+">Google+</a>
<a target="_blank" class="stackoverflow" href="https://stackoverflow.com/users/5290485/eagle" title="StackOverflow"></a>
<a target="_blank" class="github" target="_blank" href="https://github.com/zhangbo2012/" title="GitHub">GitHub</a>
<a target="_blank" class="email" href="mailto:zhangbo2012@outlook.com" title="Email">Email</a>
<a target="_blank" class="rss" href="atom.xml" title="RSS">RSS</a>
</div>
</div>
<div id="site-categories" class="side-item ">
<div class="side-header">
<h2>Categories</h2>
</div>
<div class="side-content">
<p class="cat-list">
<a href="mac.html"><strong>mac</strong></a>
<a href="python.html"><strong>python</strong></a>
<a href="java.html"><strong>java</strong></a>
<a href="operation-and-maintenance.html"><strong>运维</strong></a>
</p>
</div>
</div>
<div id="site-categories" class="side-item">
<div class="side-header">
<h2>Recent Posts</h2>
</div>
<div class="side-content">
<ul class="posts-list">
<li class="post">
<a href="python-gui-serial.html">Python 串口加GUI编程【预告】</a>
</li>
<li class="post">
<a href="python-get-and-analysis-pubg-mobile-data.html">用python分析了20万场吃鸡数据</a>
</li>
<li class="post">
<a href="why-choose-macbook.html">关于12' MacBook使用的记录</a>
</li>
<li class="post">
<a href="python-mysql-charset.html">MySQL中文乱码</a>
</li>
<li class="post">
<a href="om-ssl-config.html">HTTPS</a>
</li>
</ul>
</div>
</div>
</div><!-- sidebar -->
</div><!-- hide for small -->
</div><!-- large 4 -->
</div><!-- row -->
<div class="page-bottom clearfix">
<div class="row">
<p class="copyright">Copyright © 2015
Powered by <a target="_blank" href="http://www.mweb.im">MWeb</a>,
Theme used <a target="_blank" href="http://github.com">GitHub CSS</a>.</p>
</div>
</div>
</section>
</div>
</div>
<script src="asset/js/foundation.min.js"></script>
<script>
$(document).foundation();
function fixSidebarHeight(){
var w1 = $('.markdown-body').height();
var w2 = $('#sidebar').height();
if (w1 > w2) { $('#sidebar').height(w1); };
}
$(function(){
fixSidebarHeight();
})
$(window).load(function(){
fixSidebarHeight();
});
</script>
<script src="asset/chart/all-min.js"></script><script type="text/javascript">$(function(){ var mwebii=0; var mwebChartEleId = 'mweb-chart-ele-'; $('pre>code').each(function(){ mwebii++; var eleiid = mwebChartEleId+mwebii; if($(this).hasClass('language-sequence')){ var ele = $(this).addClass('nohighlight').parent(); $('<div id="'+eleiid+'"></div>').insertAfter(ele); ele.hide(); var diagram = Diagram.parse($(this).text()); diagram.drawSVG(eleiid,{theme: 'simple'}); }else if($(this).hasClass('language-flow')){ var ele = $(this).addClass('nohighlight').parent(); $('<div id="'+eleiid+'"></div>').insertAfter(ele); ele.hide(); var diagram = flowchart.parse($(this).text()); diagram.drawSVG(eleiid); } });});</script>
</body>
</html>