今天来聊聊闭包

闭包:就是能读取其他函数内部变量的函数。由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成”定义在一个函数内部的函数”。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
   // 此样例来此 阮一峰的个人日志
function fn1(){
var n=1;
add=function(){n=n+1}
function fn2(){
alert(n)
}
return fn2;
}
var fn=fn1()
//可以实现一个计数器
var b=function(){
var n=0;
var test=function (){
n=n+1
console.log(n)
};
return test
}
var main=b()
main(); //1
main(); //2
main(); //3
js

今天来聊聊JavaScript的 函数的多种形式

我们在项目中经常会写function, 基本就是一个需求或者一个功能我们就写一个function,这样会有很多过程,其实JavaScript也是面向对象的,我们可以尝试用对象的方式来写函数,你会发现不一样的天地。
比如我们在处理一个请假申请过程中,里面会有很多js方法,比如验证、数据格式化、异步获取等方法,我们通常的方式是n个function累加,这样有一个不好的地方就是我们会创建很多全局变量,其实我们完全可以有多种形式来处理我们的各种业务函数。

1.用对象来收编函数

1
2
3
var obj={fn:function(){
}
}

2.对象的另外一种形式

1
2
3
4
var obj=function(){};
obj.fn=fucntion(){

};

3.对象的又一种方式

1
2
3
4
5
var obj=function(){
return {
fn:function(){}
}
}

4.类的形式

1
2
3
var obj=function(){
this.fn=function(){}
}

5.原型的形式

1
2
3
4
5
6
7
8
9
10
11
12
 //形式1
var obj=function(){};
obj.prototype.fn=function(){};
//形式2
var obj1=function(){}
obj1.prototype={fn:function(){}}
//形式3
Function.prototyp.addMethods=function(name,fn){
this[name]=fn;
}
var fn=new Function()
fn.addMethods("fn1",function(){})
js

模拟登录的实现

分析下我们一般的登录过程就是向服务器发送用户和密码,服务器响应后返回一个唯一编码,把这个编码存在Cookie里,这样我们后续的访问都带着这个cookie来访问,就实现了登录过程。下来我们就来实现这两个步骤

获取cookies

  1. 首先我们用浏览器分析下登录过程。
    1). 打开网站(这里是最简单模式,没有验证码)的登录页面,打开调试器,按照下图操作进行登录。

    2). 打开第一个截图的login的资源请求如下图,主要是为了找到formdata数据。

    3). 查找formData的数据,在这里之前json对象传输请求的时候一直遇到了一些问题,后来就改成用url参数的方式来请求,请看下图。
  2. 到这里我们就可以开始撸代码了。
    1). 用node的http 模拟请求。这里注意我们要将请求的方法返回一个promise对象,这样为了将请求成功后的值传递给下一个操作。至于原因就不说了。

    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
            function getLtpaToken(){
    //创建promise 用户再次获取的时候传递cookie信息
    var p=new Promise((resolve,reject)=>{
    // 第一次请求获取 LtpaToken

    var options = {
    hostname: 'uatbx.xxx.com.cn', //这里是样例,请注意实际的域名信息
    path: "/names.nsf?Login&%25%25ModDate=0000000000000000&reasonType=0&%25%25Surrogate_locale=1&locale=zh-cn&Username="+Username+"&Password="+Password+"&RedirectTo=%2Findishare%2Fsecurtrac.nsf%2Fagttrac%3Fopenagent%26url%3D%2Findishare%2Fbxgl%2Fywjcsj.nsf%2F%28frame%29%2Fdzbx",
    headers: {
    'Content-Type': 'application/x-www-form-urlencoded',
    },
    method: 'GET'
    };
    var req = http.request(options, function (res) {
    console.log('STATUS: ' + res.statusCode);
    console.log('HEADERS: ' + JSON.stringify(res.headers));
    res.on("data",function(data){
    chunks.push(data)
    })
    res.on("end",function(){
    var cookie=JSON.stringify(res.headers)
    resolve(cookie)
    });

    });
    req.on('error', function (e) {
    console.log('problem with request: ' + e.message);
    reject( e.message)
    });

    req.end();
    })

    return p;
    }

    2). 我们根据返回过来的LtpaToken在次请求另外一个路径。我们将这个值存在headers的cookies里

    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
            // 进行登录并返回信息
    function GetInfo(cookie){
    console.log("jinlaile==="+cookie);
    var obj=JSON.parse(cookie)
    LtpaToken=obj["set-cookie"][0].split(";")[0]
    /// 第二次请求 登录
    var cookie="myusername="+Username+"; SessionID=21C724E0CA4022AA707FD502CCFDCAC9FFC8344C; indi_locale=zh-cn;"+LtpaToken
    var options1 = {
    hostname: 'uatbx.xxx.com.cn',
    path: "/ghbx/dep1/xypj.nsf/frmTongJi?OpenForm&name=",
    headers: {
    'Content-Type': 'application/x-www-form-urlencoded',
    'Cookie': cookie
    },
    method: 'GET'
    };

    var reqAgain = http.request(options1, function (res1) {
    console.log('STATUS: ' + res1.statusCode);
    console.log('HEADERS: ' + JSON.stringify(res1.headers));
    var chunks=[]
    res1.on("data",function(data){
    chunks.push(data)
    })
    res1.on("end",function(){
    // console.log(chunks)
    // 将二进制数据解码成 gb2312 编码数据
    var html = iconv.decode(Buffer.concat(chunks), 'gb2312');
    console.log(1111)
    console.log(html)
    var $ = cheerio.load(html,{decodeEntities: false});
    //获取数据table
    });
    });
    reqAgain.on('error', function (e) {
    console.log('problem with request: ' + e.message);
    });
    reqAgain.end();

    }

    3). 就是最后调用的主方法了。最终第二次请求的时候其实就能登录并返回页面html代码。

    1
    2
    3
    4
    5
    // 根据获取的ltpatoken进行登录并获取页面信息
    getLtpaToken().then((value)=>{
    console.log(value)
    GetInfo(value)
    })
  1. 后续工作, 优化代码。。。

domino 日常打卡-xml解析

其实在我们获取到domParser.Document方法后就可以用对象.来查看所有获取的方法,然后根据自己的需求来获取数据

解析xml的常用方法

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
REM
功能:将xml字符串转化为xml对象
%END REM
Function getdocflowxmltime(strXml As String ) As Double
On Error GoTo h
Dim session As New NotesSession
Dim domParser As NotesDOMParser '定义xml 文档对象
Dim documentList As NotesDOMNodeList
Dim eNode As NotesDOMElementNode
Dim i As Integer
Dim allstat As Double
'找到每条文档对应的意见文档
strXml = Replace(Replace(strXml,Chr(10),"") ,Chr(13),"")
If strXml <> "" Then
Set domParser=session.CreateDOMParser(strXml)
domParser.Process
Set documentList = domParser.Document.GetElementsByTagName ("NodeInfo") '根据实际需求来处理
For i = 1 To documentList.NumberOfEntries
Set eNode = documentList.GetItem(i)
'根据实际需求来解析
Next

End If


getdocflowxmltime=allstat


'msg(allstat)

Exit Function
h:
showerror("getdocflowxmltime")
End Function

一 创建仓库

这里要注意仓库的地址必须是你的github的帐号+github.io,比如kejunliang.github.io,否则你会在后面遇到一个坑,就是你的css样式在发布到仓库后无法正常加载。

二 打开仓库的设置页面,找到GitHub Pages

三 选择主题

四 主题选择后确定提交后就可以了

五 在浏览器访问自己在第一步设置的地址 比如kejunliang.github.io或者在GitHub Pages页面查看自己的博客地址。

六 安装hexo

每日感悟

如果改变不了环境,那么就改变自己吧。

如何在github创建个人的博客

在github创建一个项目