详解node HTTP请求客户端 - Request

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", ...}, ...]
})

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

(0)

相关推荐

  • Node.js中Request模块处理HTTP协议请求的基本使用教程

    这里来介绍一个Node.js的模块--request.有了这个模块,http请求变的超简单. Request使用超简单,同时支持https和重定向. var request = require('request'); request('http://www.google.com', function (error, response, body) { if (!error && response.statusCode == 200) { console.log(body) // 打印goo

  • node.js中的http.request.end方法使用说明

    方法说明: 完成请求发送. 如果任何一部分请求体没有被发送,它将被刷新到流. 如果指定了 data值,将在执行完 request.end() 后,再执行一条 request.write(data , encoding) 语法: 复制代码 代码如下: request.end([data], [encoding]) 接收参数: data               请求结束后输出的data值 encoding       data值得字符编码

  • Node.js中的http请求客户端示例(request client)

    Node.JS有一个request模块,可以很方便的抓取网页内容.最简单的一个示例: var request = require('request'); request('http://www.google.com', function (error, response, body) { if (!error && response.statusCode == 200) { console.log(body); } }) 由上例可以看出用request发起一个http请求确实非常简单,不过

  • node.js中的http.request方法使用说明

    方法说明: 函数的功能室作为客户端向HTTP服务器发起请求. 语法: 复制代码 代码如下: http.get(options, callback) 由于该方法属于http模块,使用前需要引入http模块(var http= require("http") ) 接收参数: option   数组对象,包含以下参数: host:                  表示请求网站的域名或IP地址(请求的地址). 默认为'localhost'. hostname:        服务器名称,主机

  • Node.js获取前端ajax提交的request信息

    今天看一下Node.js怎么获取ajax提交的request 信息 众所周知,ajax可以在不刷新整个页面的情况下实现局部刷新,这是相当好的一种方式,能够让我们动态更新信息,今天我们看一下怎么用node来接收到前端ajax提交过来的信息 下面我贴一下前端的代码 index.html的代码我就不贴了, 因为里面就只有一个按钮而已,要实现的功能是点击按钮提交ajax异步请求 主要贴一下js页面的代码 $("button").on("click",function(){

  • 详解node HTTP请求客户端 - Request

    Request是一个Node.jsNPM模块,它是一个HTTP客户端,使用简单功能确十分强大.我们可以用它来实现HTTP响应流的转接.模拟Form表单提交.支持HTTP认证.OAuth登录.自定义请求头等.下面我们来对这个模块做一个完整的介绍: 1. 安装及简单使用 安装request模块: npm install request Request设计为用最简单的方法发送HTTP请求,它还支持HTTPS请求和自动重定向跟踪: var request = require('request'); re

  • 详解node.js创建一个web服务器(Server)的详细步骤

    前言 在 node.js 中创建一个服务器非常简单,只需要使用 node.js 为我们提供的 http 模块及相关 API 即可创建一个麻雀虽小但五脏俱全的web 服务器,相比 Java/Python/Ruby 搭建web服务器的过程简单的很. http model 要想创建一个基于 node.js 的 web 服务器,你就必须使用 node.js 提供的 http 模块,node.js 中的 http 接口旨在支持传统上难以使用的协议的许多特性, 特别是,大块的.可能块编码的消息,接口永远不会

  • 详解Node.js中间件是怎样工作的

    目录 什么是 Express 中间件? 编写 Express 中间件的要求 Express中间件:基础 中间件解决什么问题?为什么要用它? 中间件函数是什么样的? 中间件链 Express中间件的类型 内置中间件 错误处理中间件 第三方级别的中间件 总结 什么是 Express 中间件? 中间件在字面上的意思是你在软件的一层和另一层中间放置的任何东西. Express 中间件是在对 Express 服务器请求的生命周期内所执行的函数. 每个中间件都可以访问其被附加到的所有路由的 HTTP 请求和

  • 详解Node.js使用token进行认证的简单示例

    本文只介绍简单的应用,关于json web token的具体介绍以及原理请参考阮一峰老师的JSON Web Token 入门教程. 使用的Node框架是koa2,前端发送ajax请求使用axios 首先创建工程目录: static中存放静态资源,views存放前端模板,server.js为后端代码. 安装必要的依赖项: "dependencies": { "@koa/router": "^8.0.8", "jsonwebtoken&qu

  • 详解Golang语言HTTP客户端实践

    目录 HTTP客户端封装 测试脚本 测试服务 最近在学习Golang语言,中间遇到一个前辈指点,有一个学习原则:Learning By Doing.跟我之前学习Java的经验高度契合.在前一段时间学习洼坑中挣扎了好几天,差点就忘记这个重要的成功经验. 那么那什么来做练习呢?当然结合当下的工作啦,所以我列了一个路线给自己,那就是从接口测试开始学起来,从功能测试到性能测试,然后掌握基本Server开发技能. 首先,得先把HTTP接口测试常用的几个功能实现了,主要是获取HTTPrequest对象,发送

  • SpringMVC详解如何映射请求数据

    目录 1.获取参数值 1.说明 2.应用实例 3.获取http请求消息头 2.获取 javabean 形式的数据 1.使用场景说明 2.应用实例 3.使用注意事项 3.获取Servlet API 1.应用实例 2.使用注意事项 1.获取参数值 1.说明 开发中,如何获取到 http://xxx/url?参数名=参数值&参数名=参数值 这个使用的非常广泛,我们看一个案例 2.应用实例 1.创建\web\requestparam\VoteHandler.java @Controller @Reque

  • 详解node服务器中打开html文件的两种方法

    本文介绍了详解node服务器中打开html文件的两种方法,分享给大家,具体如下: 方法1:利用 Express 托管静态文件,详情查看这里 方法2:使用fs模块提供的readFile方法打开文件,让其以text/html的形式输出. 代码: var express = require('express'); var fs=require("fs"); var app = express(); //方法1:通过express.static访问静态文件,这里访问的是ajax.html //

  • 详解node.js中的npm和webpack配置方法

    概述 Node.js用c++语言编写而成的,是一个基于chrome V8引擎的javascript运行环境,让javaScript的运行脱离浏览器服务端,可以使用javaScript语言书写服务器端代码 1.使用node来实现一个http服务器 下面创建了一个端口为8787的服务器.他与php,java等不同,像php本地还要基于阿帕奇服务器,node.js能用代码快速搭建一个服务器. // 引入http模块 var http = require("http"); // 调用http的

  • 详解Node使用Puppeteer完成一次复杂的爬虫

    本文介绍了详解Node使用Puppeteer完成一次复杂的爬虫,分享给大家,具体如下: 架构图 Puppeteer架构图 Puppeteer 通过 devTools 与 browser 通信 Browser 一个可以拥有多个页面的浏览器(chroium)实例 Page 至少含有一个 Frame 的页面 Frame 至少还有一个用于执行 javascript 的执行环境,也可以拓展多个执行环境 前言 最近想要入手一台台式机,笔记本的i5在打开网页和vsc的时候有明显卡顿的情况,因此打算配1台 i7

  • 详解node.js 事件循环

    Node.js 是单进程单线程应用程序,但是因为 V8 引擎提供的异步执行回调接口,通过这些接口可以处理大量的并发,所以性能非常高. Node.js 几乎每一个 API 都是支持回调函数的. Node.js 基本上所有的事件机制都是用设计模式中观察者模式实现. Node.js 单线程类似进入一个while(true)的事件循环,直到没有事件观察者退出,每个异步事件都生成一个事件观察者,如果有事件发生就调用该回调函数. 事件驱动程序 Node.js 使用事件驱动模型,当web server接收到请

随机推荐