详解node HTTP请求客户端 - Request


Posted in Javascript onMay 05, 2017

Request是一个Node.jsNPM模块,它是一个HTTP客户端,使用简单功能确十分强大。我们可以用它来实现HTTP响应流的转接、模拟Form表单提交、支持HTTP认证、OAuth登录、自定义请求头等。下面我们来对这个模块做一个完整的介绍:

1. 安装及简单使用

安装request模块:

npm install request

Request设计为用最简单的方法发送HTTP请求,它还支持HTTPS请求和自动重定向跟踪:

var request = require('request');
request('http://www.baidu.com', function (error, response, body) {
 if (!error && response.statusCode == 200) {
 console.log(body) // IT笔录主页的HTML
 }
})

引用request模块后,就可以能通过request()方法来发送HTTP请求,在不指定请求选项option时,默认为GET。在上面请求中,对URLhttp://www.baidu.com

会301重定向到http://www.baidu.com。而Request会自动跟踪URL重定向请求,默认支持10次重定向跟踪。

2. 流(stream)操作

Node.js原生HTTP模块实现了对HTTP请求和响应对象的流操作,Request同样支持基于流的操作。

如,可以将任何响应流通过pipe转接到一个文件流:

request('http://google.com/doodle.png').pipe(fs.createWriteStream('doodle.png'))

同样,可以将一个读取的文件流转接到PUT或POST请求中。这个方法会自动检查文件扩展名,并设置一个与文件扩展名对应的content-type(当该请求头未设置时):

fs.createReadStream('file.json').pipe(request.put('http://mysite.com/obj.json'))

Request也支持pipe到它自己。这样操作时,content-type和content-length将被传递到其后的PUT请求中:

request.get('http://google.com/img.png').pipe(request.put('http://mysite.com/img.png'))

与原生HTTP客户端一样,Request在收到请求响应时会发送一个'response'。事件回调函数中会包含一个response参数,它是一个http.IncomingMessage实例:

request
 .get('http://google.com/img.png')
 .on('response', function(response) {
 console.log(response.statusCode) // 200
 console.log(response.headers['content-type']) // 'image/png'
 })
 .pipe(request.put('http://mysite.com/img.png'))

当请求发生错误时,可以简单的通过监听error事件来处理:

request
 .get('http://mysite.com/doodle.png')
 .on('error', function(err) {
 console.log(err)
 })
 .pipe(fs.createWriteStream('doodle.png'))

发挥一个想象:

http.createServer(function (req, resp) {
 if (req.url === '/doodle.png') {
 if (req.method === 'PUT') {
 req.pipe(request.put('http://mysite.com/doodle.png'))
 } else if (req.method === 'GET' || req.method === 'HEAD') {
 request.get('http://mysite.com/doodle.png').pipe(resp)
 }
 }
})

也可以使用pipe()方法将一个http.ServerRequest实例转换到一个http.ServerResponse。HTTP请求方法、请求头、请求体数据会被发送:

http.createServer(function (req, resp) {
 if (req.url === '/doodle.png') {
 var x = request('http://mysite.com/doodle.png')
 req.pipe(x)
 x.pipe(resp)
 }
})

通过pipe()返回的目标流,在Nodev0.5.x+版本中,可以写到一行:

req.pipe(request('http://mysite.com/doodle.png')).pipe(resp)

而所有这些,没有一个新功能会与原功能有冲突,只是对其进行了扩展。还可以使用HTTP代理,请求会被自动重定向并跟踪:

var r = request.defaults({'proxy':'http://localproxy.com'})

http.createServer(function (req, resp) {
 if (req.url === '/doodle.png') {
 r.get('http://google.com/doodle.png').pipe(resp)
 }
})

3. Form表单

request支付application/x-www-form-urlencoded 和 multipart/form-data 编码的form 上传。multipart/related会引用multipartAPI。

application/x-www-form-urlencoded (URL编码的Form)

URL编码的Form很简单:

request.post('http://service.com/upload', {form:{key:'value'}})
// or
request.post('http://service.com/upload').form({key:'value'})
// or
request.post({url:'http://service.com/upload', form: {key:'value'}}, function(err,httpResponse,body){ /* ... */ })

multipart/form-data (Multipart Form 上传)

对于multipart/form-dataFrom文件上传,Request使用了form-data处理。大多数情况,可以通过formData选项添加上传文件:

var formData = {
 // 键-值对简单值
 my_field: 'my_value',
 // 使用 Buffers 添加数据
 my_buffer: new Buffer([1, 2, 3]),
 // 使用 Streams 添加数据
 my_file: fs.createReadStream(__dirname + '/unicycle.jpg'),
 // 通过数组添加 multiple 值
 attachments: [
 fs.createReadStream(__dirname + '/attachment1.jpg'),
 fs.createReadStream(__dirname + '/attachment2.jpg')
 ],
 // 添加可选的 meta-data 使用: {value: DATA, options: OPTIONS}
 // 对于一些流类型,需要提供手工添加 "file"-关联 
 // 详细查看 `form-data` : https://github.com/form-data/form-data
 custom_file: {
 value: fs.createReadStream('/dev/urandom'),
 options: {
 filename: 'topsecret.jpg',
 contentType: 'image/jpg'
 }
 }
};
request.post({url:'http://service.com/upload', formData: formData}, function optionalCallback(err, httpResponse, body) {
 if (err) {
 return console.error('upload failed:', err);
 }
 console.log('Upload successful! Server responded with:', body);
});

在一些更加高级的使用中,可以通过其自身的如r.form()来访问Form数据:

// NOTE: Advanced use-case, for normal use see 'formData' usage above
var r = request.post('http://service.com/upload', function optionalCallback(err, httpResponse, body) {...})
var form = r.form();
form.append('my_field', 'my_value');
form.append('my_buffer', new Buffer([1, 2, 3]));
form.append('custom_file', fs.createReadStream(__dirname + '/unicycle.jpg'), {filename: 'unicycle.jpg'});

multipart/related

在一些不同的HTTP实现中,需要在multipart/related的之前、之后或前后同时添加一个newline/CRLF(通过multipart选项)。特别是在.NET WebAPI 4.0中,需要将preambleCRLF设置为true:

request({
 method: 'PUT',
 preambleCRLF: true,
 postambleCRLF: true,
 uri: 'http://service.com/upload',
 multipart: [
 {
 'content-type': 'application/json',
 body: JSON.stringify({foo: 'bar', _attachments: {'message.txt': {follows: true, length: 18, 'content_type': 'text/plain' }}})
 },
 { body: 'I am an attachment' },
 { body: fs.createReadStream('image.png') }
 ],
 // alternatively pass an object containing additional options
 multipart: {
 chunked: false,
 data: [
 {
  'content-type': 'application/json',
  body: JSON.stringify({foo: 'bar', _attachments: {'message.txt': {follows: true, length: 18, 'content_type': 'text/plain' }}})
 },
 { body: 'I am an attachment' }
 ]
 }
 },
 function (error, response, body) {
 if (error) {
 return console.error('upload failed:', error);
 }
 console.log('Upload successful! Server responded with:', body);
 })

4. HTTP认证

在一些HTTP请求中,需要对请求对象进行身份验证。Request提供了多种身份验证方式:

request.get('http://some.server.com/').auth('username', 'password', false);
// or
request.get('http://some.server.com/', {
 'auth': {
 'user': 'username',
 'pass': 'password',
 'sendImmediately': false
 }
});
// or
request.get('http://some.server.com/').auth(null, null, true, 'bearerToken');
// or
request.get('http://some.server.com/', {
 'auth': {
 'bearer': 'bearerToken'
 }
});

当使用auth选项进,其可包含以下值:

  1. user || username
  2. pass || password
  3. sendImmediately (可选)
  4. bearer (可选)

而对于最终调用的auth(username, password, sendImmediately, bearer)方法来说,sendImmediately默认为true,这会导致一个 basic 或 bearer 认证头会被发送。如果sendImmediately设置为false,request会在收到401状态后尝试使用一个合适的认证头。

注意,也可以基于RFC 1738标准,在URL中添加认证信息。简单的是使用方式是在主机的@符号前添加user:password:

var username = 'username',
 password = 'password',
 url = 'http://' + username + ':' + password + '@some.server.com';

request({url: url}, function (error, response, body) {
 // Do more stuff with 'body' here
});

5. 自定义HTTP头

如果需要设置自定义的HTTP请求头,如:User-Agent,可以通过options对象设置。

var request = require('request');

var options = {
 url: 'https://api.github.com/repos/request/request',
 headers: {
 'User-Agent': 'request'
 }
};

function callback(error, response, body) {
 if (!error && response.statusCode == 200) {
 var info = JSON.parse(body);
 console.log(info.stargazers_count + " Stars");
 console.log(info.forks_count + " Forks");
 }
}

request(options, callback);

6. OAuth签名

Request支持OAuth 1.0。其默认使用的签名算法为 HMAC-SHA1:

// OAuth1.0 - 3-legged server side flow (Twitter example)
// step 1
var qs = require('querystring')
 , oauth =
 { callback: 'http://mysite.com/callback/'
 , consumer_key: CONSUMER_KEY
 , consumer_secret: CONSUMER_SECRET
 }
 , url = 'https://api.twitter.com/oauth/request_token'
 ;
request.post({url:url, oauth:oauth}, function (e, r, body) {
 // Ideally, you would take the body in the response
 // and construct a URL that a user clicks on (like a sign in button).
 // The verifier is only available in the response after a user has
 // verified with twitter that they are authorizing your app.

 // step 2
 var req_data = qs.parse(body)
 var uri = 'https://api.twitter.com/oauth/authenticate'
 + '?' + qs.stringify({oauth_token: req_data.oauth_token})
 // redirect the user to the authorize uri

 // step 3
 // after the user is redirected back to your server
 var auth_data = qs.parse(body)
 , oauth =
 { consumer_key: CONSUMER_KEY
 , consumer_secret: CONSUMER_SECRET
 , token: auth_data.oauth_token
 , token_secret: req_data.oauth_token_secret
 , verifier: auth_data.oauth_verifier
 }
 , url = 'https://api.twitter.com/oauth/access_token'
 ;
 request.post({url:url, oauth:oauth}, function (e, r, body) {
 // ready to make signed requests on behalf of the user
 var perm_data = qs.parse(body)
 , oauth =
 { consumer_key: CONSUMER_KEY
 , consumer_secret: CONSUMER_SECRET
 , token: perm_data.oauth_token
 , token_secret: perm_data.oauth_token_secret
 }
 , url = 'https://api.twitter.com/1.1/users/show.json'
 , qs =
 { screen_name: perm_data.screen_name
 , user_id: perm_data.user_id
 }
 ;
 request.get({url:url, oauth:oauth, qs:qs, json:true}, function (e, r, user) {
 console.log(user)
 })
 })
})

使用RSA-SHA1 签名时,可传入如下一个OAuth对象:

  1. 指定signature_method : 'RSA-SHA1'
  2. 代替consumer_secret,指定private_key字符串为 PEM format

而使用PLAINTEXT 签名,可传入如下一个OAuth对象:

  1. 指定signature_method : 'PLAINTEXT'

7. 代理

如果指定proxy(代理)选项后,所有的请求(及其后的重定向)都会连接到该代理服务器。

如果终端是一个httpsURL,代理会使用CONNECT请求连接到代理服务器。

首先会生成类似如下一个请求:

HTTP/1.1 CONNECT endpoint-server.com:80
Host: proxy-server.com
User-Agent: whatever user agent you specify

然后建立一个到endpoint-server(终端服务器)的80端口的TCP连接,并按如下返回响应:

HTTP/1.1 200 OK

默认情况下,当代理使用http进行通讯时,request会简单的生成一个标准的http代理请求。如,会像如下这样生成一个请求:

HTTP/1.1 GET http://endpoint-server.com/some-url
Host: proxy-server.com
Other-Headers: all go here

request body or whatever

通过proxyHeaderExclusiveList选项可以明确指定一些代理头,默认会按如下方式设置:

accept
accept-charset
accept-encoding
accept-language
accept-ranges
cache-control
content-encoding
content-language
content-length
content-location
content-md5
content-range
content-type
connection
date
expect
max-forwards
pragma
proxy-authorization
referer
te
transfer-encoding
user-agent
via

8. UNIX域套接字

request支持到UNIX域套接字的请求:

/* Pattern */ 'http://unix:SOCKET:PATH'
/* Example */ request.get('http://unix:/absolute/path/to/unix.socket:/request/path')

注意:SOCKET应该是一个到文件系统根目录的绝对路径。

 9. TLS/SSL协议

对于使用了TLS/SSL等安全协议的请求,可以使用相关选项如cert、key、passphrase也可以使用agentOptions选项甚至使用https.globalAgent.options来设置:

var fs = require('fs')
 , path = require('path')
 , certFile = path.resolve(__dirname, 'ssl/client.crt')
 , keyFile = path.resolve(__dirname, 'ssl/client.key')
 , caFile = path.resolve(__dirname, 'ssl/ca.cert.pem')
 , request = require('request');

var options = {
 url: 'https://api.some-server.com/',
 cert: fs.readFileSync(certFile),
 key: fs.readFileSync(keyFile),
 passphrase: 'password',
 ca: fs.readFileSync(caFile)
 }
};

request.get(options);

使用options.agentOptions

在下面示例中,我们调用一个需要API,它需要客户端SSL证书(PEM格式)用密码保护私钥(PEM格式)并禁用SSLv3协议:

var fs = require('fs')
 , path = require('path')
 , certFile = path.resolve(__dirname, 'ssl/client.crt')
 , keyFile = path.resolve(__dirname, 'ssl/client.key')
 , request = require('request');

var options = {
 url: 'https://api.some-server.com/',
 agentOptions: {
 cert: fs.readFileSync(certFile),
 key: fs.readFileSync(keyFile),
 // 或使用 `pfx` 属性替换 `cert` 和 `key`使用私钥时,证书和CA证书在 PFX 或 PKCS12 格式的文件中:
 // pfx: fs.readFileSync(pfxFilePath),
 passphrase: 'password',
 securityOptions: 'SSL_OP_NO_SSLv3'
 }
};

request.get(options);

如果强制使用SSLv3,则通过secureProtocol指定:

request.get({
 url: 'https://api.some-server.com/',
 agentOptions: {
 secureProtocol: 'SSLv3_method'
 }
});

10. 对HAR 1.2的支持

options.har属性会重写url。method, qs, headers, form, formData, body, json的值,当request.postData.params[].fileName的值不存在时,会从硬盘文件构建 multipart 数据

当HAC 请求匹配到指定规则时会执行验证检查,如果未匹配到则会跳过:

var request = require('request')
 request({
 // 将会忽略
 method: 'GET',
 uri: 'http://www.google.com',

 // HTTP 存档请求对象
 har: {
 url: 'http://www.mockbin.com/har',
 method: 'POST',
 headers: [
 {
  name: 'content-type',
  value: 'application/x-www-form-urlencoded'
 }
 ],
 postData: {
 mimeType: 'application/x-www-form-urlencoded',
 params: [
  {
  name: 'foo',
  value: 'bar'
  },
  {
  name: 'hello',
  value: 'world'
  }
 ]
 }
 }
 })

 // 一个 POST 请求会发送到 http://www.mockbin.com
 // 其请求体编码为 application/x-www-form-urlencoded,发送内容:
 // foo=bar&hello=world

 11. option所有可用参数

request()的请求格式有如下两种形式:

request(options, callback);
// 或
request(url, options, callback);

当使用request.put()、request.post()等便捷方法进行请求时,同样有如下两种形式:

request.METHOD(options, callback);
// 或
request.METHOD(url, options, callback);

options表示请求选项,其中只有>url/uri是必须参数,其它都是可选值。下面是一些常用选项:

  1. uri || url - 完整的uri字符串或可通过url.parse()解析的url对象
  2. baseUrl - 用于基本uri的远整字符串。大多使用request.defaults,如:对于大多数请求你相使用相同的域名。如果baseUrl 是 https://example.com/api/,那么请求/end/point?test=true 会匹配到https://example.com/api/end/point?test=true;当baseUrl指定后,uri选项必须是字符串。
  3. method - HTTP请求方法(默认: "GET")
  4. headers - HTTP请求头 (默认: {})

查询字符串相关选项:

  1. qs - 包含查询字符串值的对象,会被添加到uri中
  2. qsParseOptions - 用于qs.parse方法的选项对象,或者传入querystring.parse方法用于{sep:';', eq:':', options:{}}格式的对象
  3. qsStringifyOptions - 用于qs.stringify 方法的选项对象,或者传入用于querystring.stringify 方法使用{sep:';', eq:':', options:{}}格式的选项。
  4. useQuerystring - 如果true,使用querystring 来解析查询字符串,其它使用qs (默认: false)。设置为true时,你需要将数组序列化为foo=bar&foo=baz 而默认为 foo[0]=bar&foo[1]=baz

请求体相关选项:

  1. body - 可用于:PATCH, POST 和 PUT 请求的请求体(发送的数据)。必须是Buffer, String 或 ReadStream。如果json 是 true,则body 必须是一个JSON化的对象。
  2. form - 当通过对象或查询字符串发送数据时,这一选项会设置body 为包含发送值的查询字符串,并添加自动Content-type: application/x-www-form-urlencoded请求头。
  3. formData - 当发送multipart/form-data请求时使用。参见前面的Forms 一节。
  4. multipart - 包含请求头与body属性的对象。会发送一个multipart/related请求。请求时使用。参见Forms。 也可以传入一个{chunked: false, data: []},其 chunked 用于指定发送请求的 chunked 转换编码。如果非chunked请求,,不允许使用使用具有请求体流的数据项。
  5. preambleCRLF - 在multipart/form-data请求之前添加一个 newline/CRLF 边界描述
  6. postambleCRLF - 在multipart/form-data请求之后添加一个 newline/CRLF 边界描述
  7. json - 设置 body(请求体) 为JSON格式,并添加Content-type: application/json请求头。另外,也会将响应体转换为JSON格式
  8. jsonReviver - 一个reviver函数,会传递给JSON.parse() 方法用于解板响应体。
  9. jsonReplacer - 一个 replacer 函数,会传递给JSON.stringify()方法用于序列化JSON请求体

认证相关选项:

  1. auth - 包含 user || username, pass || password, 和 sendImmediately (可选)的哈希对象。
  2. oauth - 用于 OAuth HMAC-SHA1 签名的选项
  3. hawk - 用于Hawk 签名的选项。credentials 键必须包含必要的签名信息,参见hawk文档
  4. aws - object 包含 AWS 签名信息。需要有key、secret属性,同样要有bucket选项,除非已在路径中指定bucket或请求不使用 bucket (如 GET 服务)。如果要使用 AWS v4版本,则指定sign_version 选项值为 4,默认值为2。注意: 首先要 npm install aws4
  5. httpSignature - 用于HTTP Signature Scheme的先项,使用Joyent's签名库。keyId 和 key 属性必须同时指定

重定向相关选项:

  1. followRedirect - 跟踪 HTTP 3xx 响应并重定向(默认: true)。这个属性也可以指定为一个获取单个response的函数,如果重定向继续需要返回true 其它情况返回 false
  2. followAllRedirects - 跟踪非GET请求的 HTTP 3xx 响应(默认: false)
  3. maxRedirects - 最大重定向跟踪数量(默认: 10)
  4. removeRefererHeader - 当发生重定向进移聊referer头(默认: false)。注意: 如果设为 true,referer头会设置为重定向链的初始请求。

编码/压缩相关选项:

  1. encoding - 用于响应数据 setEncoding 头的编码。如果null,则 body 会返回一个 Buffer。任何情况下(除非设置为undefined) 都会将encoding 参数传递给 toString() 方法(默认为:utf8)。
  2. gzip - 如果为 true,会添加一个Accept-Encoding 头用于发送到服务器的请求内容的压缩和解压从服务器返回的数据
  3. jar - 如果 true,则记录使用的 cookies(或自定义 cookie jar)

代理相关选项:

  1. agent - 用于http(s).Agent 的代理实例
  2. agentClass - 或指定代理类
  3. agentOptions - 并传入代理选项。注: 参见 HTTPS TLS/SSL API文档 和 代理一节
  4. forever - 如果设置为 true 会使用 forever-agent
  5. pool - 描述用于请求的代理的对象。如果此选项被省略,请求将使用全局代理(当允许时)。否则,请求将搜索您的自定义代理的池。如果没有找到自定义代理,将创建一个新的代理,并将其添加到池中。注意: pool 仅在指定agent选项后可用
    1. maxSockets属性同样可用于pool对象,用于设置代理最大可创建的 sockets 连接数(如:pool: {maxSockets: Infinity})
    2. 当发送 multiple 请求时,会创建一个新的pool 对象,maxSockets 将不会按预期工作。
    3. timeout - 超时时间(毫秒)

本地代理选项:

  1. localAddress - 用于连接网络连接的本地接口
  2. proxy - 使用的HTTP代理。支持代理使用基本认证,即认证信息通过url参数发送
  3. strictSSL - 如果设置为true,则需要有效的 SSL证书。注意: 要使用自己的证书管理,则需要指定一个所创建的代理的选项。
  4. tunnel - 控制 HTTP CONNECT 连接的隧道,可为以下值:
    1. undefined (默认) - true 表示目标为 https, false 为其它方式
    2. true - 总是通过CONNECT隧道请求连接到目的 代理
    3. false - 使用GET请求方法请求目标.
  5. proxyHeaderWhiteList -发送到代理隧道的请求头白名单
  6. proxyHeaderExclusiveList - 发送到代理隧道的请求头白名单,仅用于代理而不是目标服务器

HAR相关选项:

  1. time - 为true时,则请求-响应环(包括所有重定向)在指定毫秒内提供,响应结果的回应时长为elapsedTime
  2. har - HAR 1.2 请求对象 Object,将处理从HAR格式重写匹配值
  3. callback - 或者通过选项对象传入请求回调函数。回调函数包含以下3个参灵敏:
    1. error - 错误对象(出错时存在,通常由http.ClientRequest对象返回)
    2. http.IncomingMessage对象
    3. response 响应体(String、Buffer或JSON 对象)

12. 便捷方法

Request还可以使用以HTTP方法命名的便捷方法。

request.defaults(options)

返回一个正常请求API的包装器,其默认值为所传递的options选项。

示例:

// 使用 baseRequest() 进行请求是会设置一个 'x-token' 请求头
var baseRequest = request.defaults({
 headers: {'x-token': 'my-token'}
})

// 使用 specialRequest() 进行请求时,会包含一个在 baseRequest 中设置的 'x-token' 请求头
// 还会有一个 'special' 请求头
var specialRequest = baseRequest.defaults({
 headers: {special: 'special value'}
})

request.put

与request()方法相同,但默认method: "PUT"

request.put(url)

request.patch

与request()方法相同,但默认method: "PATCH"

request.patch(url)

request.post

与request()方法相同,但默认method: "POST"

request.post(url)

request.head

与request()方法相同,但默认method: "HEAD"

request.head(url)

request.del / request.delete

与request()方法相同,但默认method: "DELETE"

request.del(url)
request.delete(url)

request.get

与request()方法相同

request.get(url)

request.cookie

创建一个新Cookie

request.cookie('key1=value1')

request.jar

创建一个新Cookie Jar

request.jar()

注:Cookie Jar用于保存所访问网站的Cookie信息

13. 使用示例

var request = require('request')
 , rand = Math.floor(Math.random()*100000000).toString()
 ;
 request(
 { method: 'PUT'
 , uri: 'http://mikeal.iriscouch.com/testjs/' + rand
 , multipart:
  [ { 'content-type': 'application/json'
  , body: JSON.stringify({foo: 'bar', _attachments: {'message.txt': {follows: true, length: 18, 'content_type': 'text/plain' }}})
  }
  , { body: 'I am an attachment' }
  ]
 }
 , function (error, response, body) {
  if(response.statusCode == 201){
  console.log('document saved as: http://mikeal.iriscouch.com/testjs/'+ rand)
  } else {
  console.log('error: '+ response.statusCode)
  console.log(body)
  }
 }
 )

 为了保持向后兼容,响应压缩默认不会启用。要访问gzip压缩的响应,需要将gzip选项设置为true。这样数据体会通过request自动解压缩,而响应的对象将未包含压缩数据。

var request = require('request')
request(
 { method: 'GET'
 , uri: 'http://www.google.com'
 , gzip: true
 }
, function (error, response, body) {
 // body 是解压缩后的 response 响应体
 console.log('server encoded the data as: ' + (response.headers['content-encoding'] || 'identity'))
 console.log('the decoded data is: ' + body)
 }
).on('data', function(data) {
 // 收到的是解压缩后的数据
 console.log('decoded chunk: ' + data)
})
.on('response', function(response) {
 // 未修改 http.IncomingMessage object
 response.on('data', function(data) {
 // 收到的是压缩数据
 console.log('received ' + data.length + ' bytes of compressed data')
 })
})

 Cookie默认是未启用的,可以通过将jar选项设置为true来启用Cookie:

var request = request.defaults({jar: true})
request('http://www.google.com', function () {
 request('http://images.google.com')
})

使用自定义的Cookie Jar,可以将jar选项设置为一个request.jar()实例:

var j = request.jar()
var request = request.defaults({jar:j})
request('http://www.google.com', function () {
 request('http://images.google.com')
})

或 

var j = request.jar();
var cookie = request.cookie('key1=value1');
var url = 'http://www.google.com';
j.setCookie(cookie, url);
request({url: url, jar: j}, function () {
 request('http://images.google.com')
})

使用自定义的Cookie存储,可以做为request.jar()的参数传入:

var FileCookieStore = require('tough-cookie-filestore');
// 这时 'cookies.json' 文件必须已经存在
var j = request.jar(new FileCookieStore('cookies.json'));
request = request.defaults({ jar : j })
request('http://www.google.com', function() {
 request('http://images.google.com')
}

Cookie存储必须是一个tough-cookie且必须支持同步操作。

在请求完成后,检查你的Cookie Jar:

var j = request.jar()
request({url: 'http://www.google.com', jar: j}, function () {
 var cookie_string = j.getCookieString(url); // "key1=value1; key2=value2; ..."
 var cookies = j.getCookies(url);
 // [{key: 'key1', value: 'value1', domain: "www.google.com", ...}, ...]
})

 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
js优化针对IE6.0起作用(详细整理)
Dec 25 Javascript
jquery获取节点名称
Apr 26 Javascript
JavaScript中setFullYear()方法的使用详解
Jun 11 Javascript
浅析JavaScript作用域链、执行上下文与闭包
Feb 01 Javascript
JavaScript中的Reflect对象详解(ES6新特性)
Jul 22 Javascript
javascript汉字拼音互转的简单实例
Oct 09 Javascript
JavaScript队列、优先队列与循环队列
Nov 14 Javascript
Canvas + JavaScript 制作图片粒子效果
Feb 08 Javascript
如何正确理解javascript的模块化
Mar 02 Javascript
JS数组操作之增删改查的简单实现
Aug 21 Javascript
vue-cli3 karma单元测试的实现
Jan 18 Javascript
javascript获取select值的方法完整实例
Jun 20 Javascript
jQuery实现简单的抽奖游戏
May 05 #jQuery
jquery中each循环的简单回滚操作
May 05 #jQuery
JavaScript仿微信打飞机游戏
Jul 05 #Javascript
fullPage.js和CSS3实现全屏滚动效果
May 05 #Javascript
jquery dataTable 获取某行数据
May 05 #jQuery
js实现数字递增特效【仿支付宝我的财富】
May 05 #Javascript
js和jquery中获取非行间样式
May 05 #jQuery
You might like
php小技巧之过滤ascii控制字符
2014/05/14 PHP
php curl 获取https请求的2种方法
2015/04/27 PHP
Zend Framework创建自己的动作助手详解
2016/03/05 PHP
Javascript valueOf 使用方法
2008/12/28 Javascript
js本身的局限性 别让javascript做太多事
2010/03/23 Javascript
JavaScript高级程序设计 阅读笔记(十四) js继承机制的实现
2012/08/14 Javascript
深入剖析JavaScript中的枚举功能
2014/03/06 Javascript
script标签属性用type还是language
2015/01/21 Javascript
jquery实现的蓝色二级导航条效果代码
2015/08/24 Javascript
jQuery实现模仿微博下拉滚动条加载数据效果
2015/12/25 Javascript
jquery实现具有嵌套功能的选项卡
2016/02/12 Javascript
详解AngularJS 模块化
2017/06/14 Javascript
详细AngularJs4的图片剪裁组件的实例
2017/07/12 Javascript
JS实现按钮添加背景音乐示例代码
2017/10/17 Javascript
vue项目中axios使用详解
2018/02/07 Javascript
使用sessionStorage解决vuex在页面刷新后数据被清除的问题
2018/04/13 Javascript
详解Vue-axios 设置请求头问题
2018/12/06 Javascript
[07:43]《辉夜杯》公开赛晋级外卡赛战队—TRG训练生活探秘
2015/12/11 DOTA
Python中关键字nonlocal和global的声明与解析
2017/03/12 Python
python使用tornado实现登录和登出
2018/07/28 Python
python使用MQTT给硬件传输图片的实现方法
2019/05/05 Python
Django认证系统实现的web页面实现代码
2019/08/12 Python
python+opencv3.4.0 实现HOG+SVM行人检测的示例代码
2021/01/28 Python
HTML5之语义标签介绍
2016/07/07 HTML / CSS
html5中的一些标签学习(心得)
2016/10/18 HTML / CSS
英国时尚服饰电商:Boohoo
2017/10/12 全球购物
意大利包包和行李箱销售网站:Bagaglio.it
2021/03/02 全球购物
医院护士求职自荐信格式
2013/09/21 职场文书
员工晚婚的请假条
2014/02/08 职场文书
桥梁工程专业求职信
2014/04/21 职场文书
小学语文教学经验交流材料
2014/06/02 职场文书
银行委托书范本
2014/09/28 职场文书
高校群众路线教育实践活动剖析材料
2014/10/10 职场文书
2016抗战胜利71周年红领巾广播稿
2015/12/18 职场文书
SQL Server数据定义——模式与基本表操作
2021/04/05 SQL Server
Java SSH 秘钥连接mysql数据库的方法
2021/06/28 Java/Android