详解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 相关文章推荐
prototype 源码中文说明之 prototype.js
Sep 22 Javascript
基于jquery的给文章加入关键字链接
Oct 26 Javascript
node.js中的querystring.unescape方法使用说明
Dec 10 Javascript
教你如何终止JQUERY的$.AJAX请求
Feb 23 Javascript
第十章之巨幕页头缩略图与警告框组件
Apr 25 Javascript
jQuery Masonry瀑布流插件使用方法详解
Jan 18 Javascript
微信小程序 地图map实例详解
Jun 07 Javascript
js实现加载页面就自动触发超链接的示例
Aug 31 Javascript
JS实现获取汉字首字母拼音、全拼音及混拼音的方法
Nov 14 Javascript
vue单个组件实现无限层级多选菜单功能
Apr 10 Javascript
在vue中v-bind使用三目运算符绑定class的实例
Sep 29 Javascript
Vue安装浏览器开发工具的步骤详解
May 12 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程序--记数器
2006/10/09 PHP
php图片缩放实现方法
2014/02/20 PHP
PHP利用APC模块实现文件上传进度条的方法
2015/01/26 PHP
PHP Header失效的原因分析及解决方法
2016/11/16 PHP
PHP explode()函数用法讲解
2019/02/15 PHP
excel操作之Add Data to a Spreadsheet Cell
2007/06/12 Javascript
javascript 变量作用域 代码分析
2009/06/26 Javascript
基于Jquery制作的幻灯片图集效果打包下载
2011/02/12 Javascript
JavaScript 学习笔记之一jQuery写法图片等比缩放以及预加载
2012/06/28 Javascript
JS兼容浏览器的导出Excel(CSV)文件的方法
2014/05/03 Javascript
jquery实现在页面加载完毕后获取图片高度或宽度
2014/06/16 Javascript
js自动生成的元素与页面原有元素发生堆叠的解决方法
2014/09/04 Javascript
深入理解JS函数的参数(arguments)的使用
2016/05/28 Javascript
javascript显示倒计时控制按钮的简单实现
2016/06/07 Javascript
简单实现js悬浮导航效果
2017/02/05 Javascript
js利用for in循环获取 一个对象的所有属性以及值的实例
2017/03/30 Javascript
Vue-cli中为单独页面设置背景色的实现方法
2018/02/11 Javascript
Vue的轮播图组件实现方法
2018/03/03 Javascript
jQuery实现的页面详情展开收起功能示例
2018/06/11 jQuery
在JavaScript中如何访问暂未存在的嵌套对象
2019/06/18 Javascript
关于layui 实现点击按钮添加一行(方法渲染创建的table)
2019/09/29 Javascript
javascript实现画板功能
2020/04/12 Javascript
小程序实现列表倒计时功能
2021/01/29 Javascript
在Python web中实现验证码图片代码分享
2017/11/09 Python
Python用imghdr模块识别图片格式实例解析
2018/01/11 Python
python os.listdir按文件存取时间顺序列出目录的实例
2018/10/21 Python
Django管理员账号和密码忘记的完美解决方法
2018/12/06 Python
对pandas的算术运算和数据对齐实例详解
2018/12/22 Python
用Python和WordCloud绘制词云的实现方法(内附让字体清晰的秘笈)
2019/01/08 Python
Python中的__init__作用是什么
2020/06/09 Python
Python环境管理virtualenv&virtualenvwrapper的配置详解
2020/07/01 Python
详解python os.path.exists判断文件或文件夹是否存在
2020/11/16 Python
SQL Server笔试题
2012/01/10 面试题
会议邀请书范文
2014/02/02 职场文书
记帐员岗位责任制
2014/02/08 职场文书
使用HTML+Css+transform实现3D导航栏的示例代码
2021/03/31 HTML / CSS