🌟前言
哈喽小伙伴们,新的专栏 Node 已开启;这个专栏里边会收录一些Node的基础知识和项目实战;今天我们带领大家初识一下 Node第三方包 Request ;让我们一起来看看吧🤘
🌟Request
Request => npm地址
HTTP请求客户端
后端开发经常会有使用http请求的情况,如:访问API或模拟web客户端请求等。业务不复杂的情况下,使用Nodejs的原生http模块的客户端功能可满足需求,但在业务较复杂时使用http模块工作量会比较大,使用第三方request模块会让http请求变的简单。request模块是一个HTTP客户端请求模块,使用非常简单,除支持一般http请求外,还可以更复杂的http请求,如:https请求、请示重定向、数据流转接、form表单提交、HTTP认证、OAuth登录、自定义HTTP header等。
名称 | 地址 |
Request | Github地址 https://github.com/request/request |
🌟安装与使用
安装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) // 请求到主页的HTML } })
🌟流(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'))
也可以使用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)
🌟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); });
🌟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选项其可包含以下值:
user || username
pass || password
sendImmediately (可选)
bearer (可选)
而对于最终调用的auth(username, password, sendImmediately, bearer)方法来说,sendImmediately默认为true,这会导致一个 basic 或 bearer 认证头会被发送。如果sendImmediately设置为false,request会在收到401状态后尝试使用一个合适的认证头。
注意,也可以基于RFC 1738标准,在URL中添加认证信息。简单的是使用方式是在主机的@符号前添加user:password:
var username = 'username', url = 'http://' + username + ':' + password + '@some.server.com'; request({url: url}, function (error, response, body) { // Do more stuff with 'body' here });
🌟自定义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);
🌟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) }) }) })
🌟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是必须参数,其它都是可选值。下面是一些常用选项:
uri || url - 完整的uri字符串或可通过url.parse()解析的url对象
baseUrl - 用于基本uri的远整字符串。大多使用request.defaults,如:对于大多数请求你相使用相同的域名。如果baseUrl 是 https://example.com/api/,那么请求/end/point?test=true 会匹配到https://example.com/api/end/point?test=true;当baseUrl指定后,uri选项必须是字符串。
method - HTTP请求方法(默认: “GET”)
headers - HTTP请求头 (默认: {})
查询字符串相关选项:
qs - 包含查询字符串值的对象,会被添加到uri中
qsParseOptions - 用于qs.parse方法的选项对象,或者传入querystring.parse方法用于{sep:‘;’, eq:‘:’, options:{}}格式的对象
qsStringifyOptions - 用于qs.stringify 方法的选项对象,或者传入用于querystring.stringify 方法使用{sep:‘;’, eq:‘:’, options:{}}格式的选项。
useQuerystring - 如果true,使用querystring 来解析查询字符串,其它使用qs (默认: false)。设置为true时,你需要将数组序列化为foo=bar&foo=baz 而默认为 foo[0]=bar&foo[1]=baz
请求体相关选项:
body - 可用于:PATCH, POST 和 PUT 请求的请求体(发送的数据)。必须是Buffer, String 或 ReadStream。如果json 是 - true,则body 必须是一个JSON化的对象。
form - 当通过对象或查询字符串发送数据时,这一选项会设置body 为包含发送值的查询字符串,并添加自动Content-type: application/x-www-form-urlencoded请求头。
formData - 当发送multipart/form-data请求时使用。参见前面的Forms 一节。
multipart - 包含请求头与body属性的对象。会发送一个multipart/related请求。请求时使用。参见Forms。
也可以传入一个{chunked: false, data: []},其 chunked 用于指定发送请求的 chunked 转换编码。如果非chunked请求,,不允许使用使用具有请求体流的数据项。
preambleCRLF - 在multipart/form-data请求之前添加一个 newline/CRLF 边界描述
postambleCRLF - 在multipart/form-data请求之后添加一个 newline/CRLF 边界描述
json - 设置 body(请求体) 为JSON格式,并添加Content-type: application/json请求头。另外,也会将响应体转换为JSON格式
jsonReviver - 一个reviver函数,会传递给JSON.parse() 方法用于解板响应体。
jsonReplacer - 一个 replacer 函数,会传递给JSON.stringify()方法用于序列化JSON请求体
认证相关选项:
auth - 包含 user || username, pass || password, 和 sendImmediately (可选)的哈希对象。
oauth - 用于 OAuth HMAC-SHA1 签名的选项
hawk - 用于Hawk 签名的选项。credentials 键必须包含必要的签名信息,参见hawk文档
aws - object 包含 AWS 签名信息。需要有key、secret属性,同样要有bucket选项,除非已在路径中指定bucket或请求不使用 - bucket (如 GET 服务)。如果要使用 AWS v4版本,则指定sign_version 选项值为 4,默认值为2。注意: 首先要 npm install aws4
httpSignature - 用于HTTP Signature Scheme的先项,使用Joyent’s签名库。keyId 和 key 属性必须同时指定
重定向相关选项:
followRedirect - 跟踪 HTTP 3xx 响应并重定向(默认: true)。这个属性也可以指定为一个获取单个- - - response的函数,如果重定向继续需要返回true 其它情况返回 false
followAllRedirects - 跟踪非GET请求的 HTTP 3xx 响应(默认: false)
maxRedirects - 最大重定向跟踪数量(默认: 10)
removeRefererHeader - 当发生重定向进移聊referer头(默认: false)。注意: 如果设为 true,referer头会设置为重定向链的初始请求。
编码/压缩相关选项:
encoding - 用于响应数据 setEncoding 头的编码。如果null,则 body 会返回一个 Buffer。任何情况下(除非设置为undefined) 都会将encoding 参数传递给 toString() 方法(默认为:utf8)。
gzip - 如果为 true,会添加一个Accept-Encoding 头用于发送到服务器的请求内容的压缩和解压从服务器返回的数据
jar - 如果 true,则记录使用的 cookies(或自定义 cookie jar)
代理相关选项:
agent - 用于http(s).Agent 的代理实例
agentClass - 或指定代理类
agentOptions - 并传入代理选项。注: 参见 HTTPS TLS/SSL API文档 和 代理一节
forever - 如果设置为 true 会使用 forever-agent
pool - 描述用于请求的代理的对象。如果此选项被省略,请求将使用全局代理(当允许时)。否则,请求将搜索您的自定义代理的池。如果没有找到自定义代理,将创建一个新的代理,并将其添加到池中。注意: pool 仅在指定agent选项后可用
maxSockets属性同样可用于pool对象,用于设置代理最大可创建的 sockets 连接数(如:pool: {maxSockets: Infinity})
当发送 multiple 请求时,会创建一个新的pool 对象,maxSockets 将不会按预期工作。
timeout - 超时时间(毫秒)
本地代理选项:
localAddress - 用于连接网络连接的本地接口
proxy - 使用的HTTP代理。支持代理使用基本认证,即认证信息通过url参数发送
strictSSL - 如果设置为true,则需要有效的 SSL证书。注意: 要使用自己的证书管理,则需要指定一个所创建的代理的选项。
tunnel - 控制 HTTP CONNECT 连接的隧道,可为以下值:
undefined (默认) - true 表示目标为 https, false 为其它方式
true - 总是通过CONNECT隧道请求连接到目的 代理
false - 使用GET请求方法请求目标.
proxyHeaderWhiteList -发送到代理隧道的请求头白名单
proxyHeaderExclusiveList - 发送到代理隧道的请求头白名单,仅用于代理而不是目标服务器
HAR相关选项:
time - 为true时,则请求-响应环(包括所有重定向)在指定毫秒内提供,响应结果的回应时长为elapsedTime
har - HAR 1.2 请求对象 Object,将处理从HAR格式重写匹配值
callback - 或者通过选项对象传入请求回调函数。回调函数包含以下3个参灵敏:
error - 错误对象(出错时存在,通常由http.ClientRequest对象返回)
http.IncomingMessage对象
response 响应体(String、Buffer或JSON 对象)
🌟便捷方法
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信息
🌟写在最后
更多Node知识以及API请大家持续关注,尽请期待。各位小伙伴让我们 let’s be prepared at all times!