在试用node.js 模拟登陆时遇到一个问题
发布于 21天前 作者 jsanswer1 320 次浏览 来自 问答

直接上代码:

var request = require('request');
var request = request.defaults({jar: true});
request.post({url:'http://example.com/login', form: {username:'username', password:'password'}}, callback);
function callback(err, res, body){
    if(err){
         console.log(err);
    }
    console.log(body);   // -> 1
    request('http://example.com', callback2);  // -> 2
}
function callback2(err, res, data) {
     if (!err && res.statusCode == 200) {
         console.log(data);
    }
}

在 2 处并没有取得想要的主页内容,并没有登录,但1 处打印出已登录,请问如何保持登录状态呢?

10 回复

var rJar = request.jar(); 每次请求的时候带上{jar: rJar}

@steamwheedle var request = request.defaults({jar: true}); 的效果和 var rJar = request.jar(); 是一样的吧?

@jsanswer1 是一样的,但曾经碰到过{jar: true}丢失的情况,是这么解决的。 不清楚你是登录的哪个网站,也许实际上登录成功了,但那个页面是js判断cookie,ajax局布刷新的,可能性挺多的。

@steamwheedle 就比如登录Github, https://github.com/login,第一次POST请求模拟表单登录, 第二次GET请求https://github.com/login,这时应该会跳转首页,但结果并不是预期结果,依然是login这个页面

@jsanswer1

var request = require('request');
var cheerio = require('cheerio');

var jar = request.jar();

request({
    url: 'https://github.com/login',
    method: 'GET',
    jar: jar
}, function(err, res, body) {

    if (res.statusCode === 200) {
        console.log('ok1');

        var $ = cheerio.load(res.body);

        var form = {
            utf8: true,
            authenticity_token: $('input[name="authenticity_token"]').val(),
            login: '',
            password: ''
        };

        request({
            url: 'https://github.com/session',
            method: 'POST',
            form: form,
            jar: jar
        }, function(err, res, body) {
            if (res.statusCode === 302) {
                console.log('ok2');

                request({
                    url: 'https://github.com/login',
                    method: 'GET',
                    jar: jar
                    //followRedirect: false
                }, function(err, res, body) {
                    if (res.statusCode === 200) {
                        console.log('ok3');
                        var $ = cheerio.load(res.body);
                        console.log($('.repo').html());
                    }
                });
            }
        })
    }
});

// ok1
// ok2
// ok3
// tpsw.github.io

@steamwheedle 感谢热心回答,我想我应该是有两个地方出了问题: 1,authenticity_token 没有带进去 2,发送post请求的地址不对 是这两个问题吧? 还有就是为什么需要带入 authenticity_token这个值呢?

@jsanswer1 authenticity_token参数是每次表单请求都要提交的,主要是为了确认当前用户的身份,抵御csrf攻击。

@steamwheedle 恩,查询了相关资料了解了,再次感谢!

@jsanswer1 如果是模拟登陆微博的话,怎么办?按上边那个方法不行啊

回到顶部