我想创建一个类,该类将发送一个post请求(登录),保存cookie并将该cookie用于其他操作,如下载文件。
我创建了一个本地服务器,该服务器将接收带有用户名和密码的post http方法以及一个名为/download
的路由器,只有在用户登录后才能访问该路由器,否则它将返回你需要登录
。
问题是: 这是我的类的原型(事先):
const request = require('request-promise-native')
class ImageDownloader {
constructor(username = null, password = null) {
this.username = username
this.password = password
this.cookie = request.jar()
this.init()
}
init() {
// login and get the cookie
}
download() {
// needs the cookie
}
query() {
// needs the cookie
}
}
如您在上方的代码中所看到的,我需要使用Cookie进行两个操作,即下载
和查询
。因此,我考虑创建一个init
方法来执行登录等初始操作,并在构造函数中调用它,以使其初始化并将cookie放入变量this.cookie
中以供全局使用,但它没有起作用,似乎init
在其他所有方法之后被调用。
const request = require('request-promise-native')
class ImageDownloader {
constructor(username = null, password = null) {
this.username = username
this.password = password
this.cookie = request.jar()
this.init()
}
async init() {
await request({
uri: 'http://localhost/login',
jar: this.cookie,
method: 'post',
formData: {
'username': 'admin',
'password': 'admin'
}
}).catch(e => console.error(e))
}
async download() {
await request({
uri: 'http://localhost/download/image.jpg',
jar: this.cookie
})
.then(b => console.log(b))
.catch(e => console.error(e))
}
query() {
// ...
}
}
const downloader = new ImageDownloader
downloader.download()
服务器响应:返回给我的是需要登录... 但如果我进行以下更改,它就可以工作:
async download() {
await init() // <<<<<<<<<<<<
await request({
uri: 'http://localhost/download/image.jpg',
jar: this.cookie
})
.then(b => console.log(b))
.catch(e => console.error(e))
}
只有在download
方法中调用init
,它才能正常工作。
如果我将console.log(this.cookie)
放在download
中,则返回一个空的CookieJar
,如果我将相同的东西放在init
中,则会返回正确的cookie,但是它似乎出现在download
执行之后,尽管我在调用download
之前在构造函数中调用了它。
如何解决?非常感谢。
@编辑
我按照@agm1984和@Jaromanda X告诉我的更改,但它仍然不起作用 :(
const request = require('request-promise-native')
class ImageDownloader {
constructor(username = null, password = null) {
this.username = username
this.password = password
this.cookie = request.jar()
this.init().catch(e => console.error(e))
}
async init() {
return await request({
uri: 'http://localhost/login',
jar: this.cookie,
method: 'post',
formData: {
'username': 'admin',
'password': 'admin'
}
})
}
async download() {
return await request({
uri: 'http://localhost/download/image.jpg',
jar: this.cookie
})
}
query() {
// ...
}
}
const downloader = new ImageDownloader
downloader.download()
.then(b => console.log(b))
.catch(e => console.error(e))
但是再怎么样...只有在我调用download
函数内部的init
函数时才能起作用。
init
和download
内部的操作不需要在任何地方共享,并且request-promise-native
会将jar放入this.cookie
中(我所需要的),但问题是运行顺序。在download
中添加await init()
的行为就像“我必须等待init
完成然后继续”(大致如此),但由于我在构造函数中调用了this.init
,所以我认为这是不必要的。 - vajehudownload
不会等待init
。 - Jaromanda Xthis.initp = this.init();
... 然后在download
中将await this.initp;
添加为第一行。 - Jaromanda Xinit
,所以我想:我能不能创建一个方法,在构造函数中只调用一次,然后在其他地方随处使用呢?理论上看起来很完美,但实际上并不是这样。我认为await
可以解决问题,并且由于我正在使用ImageDownloader
的具体方法调用download
,所以我认为它会在init
之后调用download
。 - vajehu