淘宝新版UA算法中的UA_InputId/LogVal/log
淘宝UA算法文件更新的UA字符串有三个去处:为页面中ID为UA_InputId的元素的value属性赋值;赋值给UA_Opt[“LogVal”];根据相关初始设定,以image方式回传至服务器。本文记录UA字符串前往三个去处的方式。
64.js原文件的下载链接http://af.alicdn.com/js/cj/64.js(该链接已失效),该文件反混淆之后的文件的下载链http://pan.baidu.com/s/1o8ep0r4 。本文记录64.js的函数结构及主要函数的功能概述。
在淘宝UA算法UA来源信息加密方案浅析(201605)一文中提及,每次UA信息更新时都会调用主函数参数中序号9的输出函数名为s的子函数。本文中关于主函数与子函数的概念请参阅2016新版淘宝UA算法文件功能框架的粗浅分析。输出函数名为s的函数实际名称为M,其代码如下所示。
1 2 3 |
function M(n) { $ && (q.formSend && I(n), q.asyncSend && (x.push(n), T()), q.logSend && A(n)); } |
其中q.formSend, q.asyncSend, q.logSend是来源于Ua_Opt的初始设定,而与它们一起做&&运算的函数则是各自事件的处理函数。接下来,我们先来了解一下UA_Opt。
UA_Opt
淘宝旧版的UA文件(请参阅ua.js中UA_Opt设定信息的重要性与来源分析)也包含变量UA_Opt。当时我猜测这个变量来源于外部文件,但是我那时并没有找到其来源。后来经过几位大神的指点,我终于发现了UA_opt变量的踪迹。
UA_opt定义在https://login.taobao.com/member/login.jhtml?from=taobaoindex&style=⊂=true&redirect_url=http%3A%2F%2Fi.taobao.com %2Fmy_taobao.htm%3Fspm%3Da21bo.50862.1997525045.1.Bgkr7B中,其定义代码如下:
1 2 3 |
var UA_Opt = {}; UA_Opt.ExTarget = ['TPL_password_1','TPL_password_2','J_Pwd1','J_PwdV']; UA_Opt.FormId = "J_Form"; |
而绝大部分变量的赋值则在nc.js中,链接为https://g.alicdn.com/sd/ncpc/nc.js?t=2016060220。在nc.js中定义的变量与当前的研究文件中提及的变量基本相符,如下图所示,当前研究对象取用UA_opt的相关代码在调用主函数参数中序号6的函数中。
UA_InputId
为页面中ID为UA_InputId的元素的value属性赋值的处理函数是I(n),如下代码所示:
1 2 3 4 5 6 7 8 9 10 11 |
function I(n) {//q.formSend && l(n) //判断q.FormId是否为字符串类型,是则返回true //获取ID为UA_InputId的元素并赋值给input,input未加var定义,所以它是全局变量? if (C(q.FormId) && (input = Q.getElementById(W.inputId), input)) { var t = R.app(n); input.value = X.encode(t), H.fire('s.f', { getOrAddFormInput : L }); } } |
该函数的执行顺序:
1. 判断UA_Opt.FormId是否为字符串类型,是则执行第2步,否则当前函数结束。
2. 获取元素ID为UA_InputId的元素并赋值给变量input。据javascript的语法,未加var使用的变量属于全局变量。那么这里的input就是全局变量了?
3. input变量是否已定义,是则执行第4步,否则函数结束。
4. 对当前UA信息加密,并赋值给input.value。
5. 驱动事件s.f。
事件s.f和s.a均与image回传信息有关,待记录完image回传处理函数,再来记录s.f与s.a。
Image&Log
每一次UA信息更新时,通过image回传信息的函数执行流程如下图所示:
由图可知,每一次UA信息更新时,会根据当前UA信息更新的次数与初始设定值来决定是否回传,暂把这种方式称为定量调用,定量调用的函数是S。除此之外,还有如下两种情况会调用函数S。
1.也会根据初始设定值进行定时调用setInterval(S, UA_Opt.SendTimer);
2.当用户离开页面时会调用S(1).
s.f & s.a
事件s.f和s.a在主函数参数中序号为14的函数中被监听,在主函数参数中序号为9的函数中被驱动,两个函数的功能如下图所示。
结合这两个函数的功能与Image部分的代码可知,最终回传至服务器的信息类型为:“n=UA累积加密信息”+”a=(pointman.getAppKey)”+”t=(pointman.getToken)”+”scene=(pointman.config.common.scene)”+”p=(E.parser.json_encode(M.get().Custom))”+”asyn=(0或1)”,上述内容中括号中的内容是加密后的信息。这一点是旧版ua.js文件中所没有的ua.js中用 image 对象实现页面访问统计。
LogVal
LogVal的处理函数为A(n),相应代码如下。该函数会先判断UA_Opt.LogVal值是否不为零,若不为零,则获取ID为UA_InputId的元素,该元素存在且已有值,则获取该元素的值赋值给window.UA_Opt.LogVal。
1 2 3 4 5 6 7 8 9 10 11 |
function A(n) {//q.logSend if (q.LogVal) { var a = Q.getElementById(W.inputId);//W.inputId:UA_InputId if (a && a.value) z[q.LogVal] = a.value;//z:window else { var e = R.app(n); z[q.LogVal] = X.encode(e); } } } |