一、连接过程继续解读-----fun33-fun37解读
完整代码如下:
//fun33-37 console.error('fun35-37==>2332==>2332'); var q = window.MediaStream; void 0 === q && "undefined" != typeof webkitMediaStream && (q = webkitMediaStream), void 0 !== q && ( "getVideoTracks" in q.prototype || (q.prototype.getVideoTracks = function() { console.info('fun3537.03b==>2348==>2348'); if (!this.getTracks) return []; var e = []; return this.getTracks.forEach(function(n) { -1 !== ("" + n.kind).indexOf("video") && e.push(n) }), e }, console.info('fun3537.04==>2357==>2357'), q.prototype.getAudioTracks = function() { console.info('fun3537.04==>2356==>2356'); if (!this.getTracks) return []; var e = []; return this.getTracks.forEach(function(n) { -1 !== ("" + n.kind).indexOf("audio") && e.push(n) }), e }), console.info('fun3537.05==>2367==>2367'), "stop" in q.prototype || (q.prototype.stop = function() { console.info('fun3537.05==>2367==>2367'); this.getAudioTracks().forEach(function(e) { e.stop && e.stop() }), this.getVideoTracks().forEach(function(e) { e.stop && e.stop() }) }) ),
1.1 代码段一
var q = window.MediaStream;
q是个函数,用于获取媒体数据。
1.2 代码段二
void 0 === q && "undefined" != typeof webkitMediaStream && (q = webkitMediaStream),
注:经测试,void ===q为false,所以就没必要向后执行了,实际上,webkitMediaStream也是个函数,不是undefined.
1.3 代码段三
void 0 !== q && ( console.info('fun3537.03a==>2345==>2345')&& "getVideoTracks" in q.prototype || (q.prototype.getVideoTracks = function() { console.info('fun3537.03b==>2348==>2348'); if (!this.getTracks) return []; var e = []; return this.getTracks.forEach(function(n) { -1 !== ("" + n.kind).indexOf("video") && e.push(n) }), e },
注:q.prototype是向对象里面添加属性的方法,如下:
因为"getVideoTracks" in q.prototype是成立的,所以,后面的函数没有走。
1.4 代码段四
console.info('fun3537.04==>2357==>2357'), q.prototype.getAudioTracks = function() { console.info('fun3537.04==>2356==>2356'); if (!this.getTracks) return []; var e = []; return this.getTracks.forEach(function(n) { -1 !== ("" + n.kind).indexOf("audio") && e.push(n) }), e })
注:这个函数是紧接着上面那个函数,逗号表达式里面的。 因为"getVideoTracks" in q.prototype成立,就不走这个函数了。
1.5 代码段五
console.info('fun3537.05a==>2367==>2367'), "stop" in q.prototype || (q.prototype.stop = function() { console.info('fun3537.05b==>2367==>2367'); this.getAudioTracks().forEach(function(e) { e.stop && e.stop() }), this.getVideoTracks().forEach(function(e) { e.stop && e.stop() }) }) ),
注:如果成立,就是说如果stop在q.prototype中,就不管了,如果不在就定义个函数过去。
二、连接过程继续解读-----fun38尝试理解
2.1 fun38代码整体
整体代码太多,不再展示,只能分段展示。
2.2 fun38.01
//fun38.01 function e() { var e, n, t, o = (c.appVersion, c.userAgent), i = c.appName, r = "" + parseFloat(c.appVersion), s = parseInt(c.appVersion, 10); if (f) { i = "Opera"; try { r = c.userAgent.split("OPR/")[1].split(" ")[0], s = r.split(".")[0] } catch (a) { r = "0.0.0.0", s = 0 } } else g ? (n = o.indexOf("MSIE"), i = "IE", r = o.substring(n + 5)) : v ? (n = o.indexOf("Chrome"), i = "Chrome", r = o.substring(n + 7)) : p ? (n = o.indexOf("Safari"), i = "Safari", r = o.substring(n + 7), -1 !== (n = o.indexOf("Version")) && (r = o.substring(n + 8))) : m ? (n = o.indexOf("Firefox"), i = "Firefox", r = o.substring(n + 8)) : (e = o.lastIndexOf(" ") + 1) < (n = o.lastIndexOf("/")) && (i = o.substring(e, n), r = o.substring(n + 1), i.toLowerCase() === i.toUpperCase() && (i = c.appName)); return l && (i = "Edge", r = "" + parseInt(c.userAgent.match(/Edge/(d+).(d+)$/)[2], 10)), -1 !== (t = r.indexOf(";")) && (r = r.substring(0, t)), -1 !== (t = r.indexOf(" ")) && (r = r.substring(0, t)), s = parseInt("" + r, 10), isNaN(s) && (r = "" + parseFloat(c.appVersion), s = parseInt(c.appVersion, 10)), { fullVersion: r, version: s, name: i, isPrivateBrowsing: !1 } }
分析如下:
1)定义几个变量如下:
var e, n, t, o = (c.appVersion, c.userAgent), i = c.appName, r = "" + parseFloat(c.appVersion), s = parseInt(c.appVersion, 10);
a.) e,n,t定义的值是一样的,都是未定义。如下:
b.) o = (c.appVersion, c.userAgent),
对于o来说,c.userAgent是o的最终值,哪怕为空。
注:现在的关键问题是o = (c.appVersion, c.userAgent)中c从哪里来的。
c.) i,r,s
注:i,r,s的值上面截图中已给出,不再详述。
2)代码段二
if (f) { i = "Opera"; try { r = c.userAgent.split("OPR/")[1].split(" ")[0], s = r.split(".")[0] } catch (a) { r = "0.0.0.0", s = 0 } }
注:经打日志,f为false,从代码可知,f用于判断是不是Opera浏览器,false表示不是,true表示是。不是的话,就不走下面里的代码,直接看else即可。
3)代码段三
else g ? (n = o.indexOf("MSIE"), i = "IE", r = o.substring(n + 5)) : v ? (n = o.indexOf("Chrome"), i = "Chrome", r = o.substring(n + 7)) : p ? (n = o.indexOf("Safari"), i = "Safari", r = o.substring(n + 7),
1)g
看g成立不成立,g为false,说明不是IE浏览器。
2)g不成立
走如下:
v ? (n = o.indexOf("Chrome"), i = "Chrome", r = o.substring(n + 7))
: p ? (n = o.indexOf("Safari"), i = "Safari", r = o.substring(n + 7)
注:v成立不成立,v成立,说明是Chrome浏览器。