在试用node.js 模拟登陆时遇到一个问题
发布于 9 年前 作者 jsanswer1 5660 次浏览 最后一次编辑是 8 年前 来自 问答

直接上代码:

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 如果是模拟登陆微博的话,怎么办?按上边那个方法不行啊

回到顶部