cp from : https://blog.csdn.net/gebitan505/article/details/58585846html
superagent
是nodejs里一个很是方便的客户端请求代理模块,当你想处理get,post,put,delete,head
请求时,你就应该想起该用它了:)node
superagent 是一个轻量的,渐进式的ajax api,可读性好,学习曲线低,内部依赖nodejs原生的请求api,适用于nodejs环境下.git
一个简单的post请求,并设置请求头信息的例子github
request .post('/api/pet') .send({ name: 'Manny', species: 'cat' }) .set('X-API-Key', 'foobar') .set('Accept', 'application/json') .end(function(res){ if (res.ok) { alert('yay got ' + JSON.stringify(res.body)); } else { alert('Oh no! error ' + res.text); } });
这个连接文档,是用Mocha’s文档自动输出的,下面提供了这个测试文档对应的源文件ajax
一个请求的初始化能够用请求对象里合适的方法来执行,而后调用end()
来发送请求,下面是一个简单的get
请求json
request .get('/search') .end(function(res){ });
请求方法也能够经过参数传递:api
request('GET', '/search').end(callback);
node
客户端也容许提供绝对路径:跨域
request .get('http://example.com/search') .end(function(res){ });
delete,head,post,put
和别的http动做均可以使用,来换个方法看看:服务器
request .head('/favicon.ico') .end(function(res){ });
delete
是一个特列,由于它是系统保留的关键字,因此应该用.del()
这个名字:restful
request .del('/user/1') .end(function(res){ });
http请求默认的方法为get
,因此就像你看到的,下面的这个例子也是可用的:
request('/search', function(res){ });
设置头字段很是简单,只需调用.set()
方法,传递一个名称和值就行:
request .get('/search') .set('API-Key', 'foobar') .set('Accept', 'application/json') .end(callback);
你也能够直接传递一个对象进去,这样一次就能够修改多个头字段:
request .get('/search') .set({ 'API-Key': 'foobar', Accept: 'application/json' }) .end(callback);
当使用get
请求传递查询字符串的时候,用.query()
方法,传递一个对象就能够,下面的代码将产生一个/search?query=Manny&range=1..5&order=desc
请求:
request .get('/search') .query({ query: 'Manny' }) .query({ range: '1..5' }) .query({ order: 'desc' }) .end(function(res){ });
或者传一个单独的大对象:
request .get('/search') .query({ query: 'Manny', range: '1..5', order: 'desc' }) .end(function(res){ });
.query()
方法也容许传递字符串:
request .get('/querystring') .query('search=Manny&range=1..5') .end(function(res){ });
或者字符串拼接:
request .get('/querystring') .query('search=Manny') .query('range=1..5') .end(function(res){ });
一个典型的json post请求看起来就像下面的那样,设置一个合适的Content-type
头字段,而后写入一些数据,在这个例子里只是json字符串:
request.post('/user') .set('Content-Type', 'application/json') .send('{"name":"tj","pet":"tobi"}') .end(callback)
由于json很是通用,因此就做为默认的Content-type
,下面的例子跟上面的同样:
request.post('/user') .send({ name: 'tj', pet: 'tobi' }) .end(callback)
或者调用屡次.send()
方法:
request.post('/user') .send({ name: 'tj' }) .send({ pet: 'tobi' }) .end(callback)
默认发送字符串,将设置Content-type
为application/x-www-form-urlencoded
,屡次调用将会经过&
来链接,这里的结果为name=tj&pet=tobi
:
request.post('/user') .send('name=tj') .send('pet=tobi') .end(callback);
superagent的请求数据格式化是能够扩展的,不过默认支持form
和json
两种格式,想发送数据以application/x-www-form-urlencoded
类型的话,则能够简单的调用.type()
方法传递form
参数就行,这里默认是json
,下面的请求将会postname=tj&pet=tobi
内容:
request.post('/user') .type('form') .send({ name: 'tj' }) .send({ pet: 'tobi' }) .end(callback)
注意:form
是form-data
和urlencoded
的别名,为了向后兼容
常见的方案是使用.set()
方法:
request.post('/user') .set('Content-Type', 'application/json')
一个简便的方法是调用.type()
方法,传递一个规范的MIME
名称,包括type/subtype
,或者一个简单的后缀就像xml
,json
,png
这样,例如:
request.post('/user') .type('application/json') request.post('/user') .type('json') request.post('/user') .type('png')
跟.type()
简便方法同样,这里也能够调用.accept()
方法来设置接受类型,这个值将会被request.types
所引用,支持传递一个规范的MIME
名称,包括type/subtype
,或者一个简单的后缀就像xml
,json
,png
这样,例如:
request.get('/user') .accept('application/json') request.get('/user') .accept('json') request.get('/user') .accept('png')
当用.send(obj)
方法来发送一个post请求,而且但愿传递一些查询字符串,能够调用.query()
方法,好比向?format=json&dest=/login
发送post请求:
request .post('/') .query({ format: 'json' }) .query({ dest: '/login' }) .send({ post: 'data', here: 'wahoo' }) .end(callback);
superagent会解析一些经常使用的格式给请求者,当前支持application/x-www-form-urlencoded
,application/json
,multipart/form-data
.
res.body
是解析后的内容对象,好比一个请求响应'{"user":{"name":"tobi"}}'
字符串,res.body.user.name
将会返回tobi
,一样的,x-www-form-urlencoded
格式的user[name]=tobi
解析完的值,也是同样的.
nodejs
客户端经过Formidable
模块来支持multipart/form-data
类型,当解析一个multipart
响应时,res.files
属性就能够用.假设一个请求响应下面的数据:
--whoop Content-Disposition: attachment; name="image"; filename="tobi.png" Content-Type: image/png ... data here ... --whoop Content-Disposition: form-data; name="name" Content-Type: text/plain Tobi --whoop--
你将能够获取到res.body.name
名为’Tobi’,res.files.image
为一个file
对象,包括一个磁盘文件路径,文件名称,还有其它的文件属性.
响应通常会提供不少有用的标识以及属性,都在response
对象里,按照respone.text
,解析后的response.body
,头字段,一些标识的顺序来排列.
res.text
包含未解析前的响应内容,通常只在mime
类型可以匹配text/
,json
,x-www-form-urlencoding
的状况下,默认为nodejs客户端提供,这是为了节省内存.由于当响应以文件或者图片大内容的状况下影响性能.
跟请求数据自动序列化同样,响应数据也会自动的解析,当为一个Content-Type
定义一个解析器后,就能自动解析,默认解析包含application/json
和application/x-www-form-urlencoded
,能够经过访问res.body
来访问解析对象.
res.header
包含解析以后的响应头数据,键值都是node处理成小写字母形式,好比res.header['content-length']
.
Content-Type
响应头字段是一个特列,服务器提供res.type
来访问它,默认res.charset
是空的,若是有的话,则自动填充,例如Content-Type
值为text/html; charset=utf8
,则res.type
为text/html
,res.charst
为utf8
.
响应状态标识能够用来判断请求是否成功,除此以外,能够用superagent来构建理想的restful
服务器,这些标识目前定义为:
var type = status / 100 | 0; // status / class res.status = status; res.statusType = type; // basics res.info = 1 == type; res.ok = 2 == type; res.clientError = 4 == type; res.serverError = 5 == type; res.error = 4 == type || 5 == type; // sugar res.accepted = 202 == status; res.noContent = 204 == status || 1223 == status; res.badRequest = 400 == status; res.unauthorized = 401 == status; res.notAcceptable = 406 == status; res.notFound = 404 == status; res.forbidden = 403 == status;
能够经过req.abort()
来停止请求.
能够经过req.timeout()
来定义超时时间,而后当超时错误发生时,为了区别于别的错误,err.timeout
属性被定义为超时时间,注意,当超时错误发生后,后续的请求都会被重定向.不是每一个请求.
nodejs客户端能够经过两种方式来达到验证的目的,第一个是传递一个像这样的url,user:pass
:
request.get('http://tobi:learnboost[@local](/user/local)').end(callback);
第二种是调用.auth()
方法:
request .get('http://local') .auth('tobo', 'learnboost') .end(callback);
默认是向上跟随5个重定向,不过能够经过调用.res.redirects(n)
来设置个数:
request .get('/some.png') .redirects(2) .end(callback);
nodejs客户端容许使用一个请求流来输送数据,好比请求一个文件做为输出流:
var request = require('superagent') , fs = require('fs'); var stream = fs.createReadStream('path/to/my.json'); var req = request.post('/somewhere'); req.type('json'); stream.pipe(req);
或者输送一个响应流到文件中:
var request = require('superagent') , fs = require('fs'); var stream = fs.createWriteStream('path/to/my.json'); var req = request.get('/some.json'); req.pipe(stream);
superagent用来构建复合请求很是不错,提供了低级和高级的api方法.
低级的api是使用多个部分来表现一个文件或者字段,.part()
方法返回一个新的部分,提供了跟request
自己类似的api方法.
var req = request.post('/upload'); req.part() .set('Content-Type', 'image/png') .set('Content-Disposition', 'attachment; filename="myimage.png"') .write('some image data') .write('some more image data'); req.part() .set('Content-Disposition', 'form-data; name="name"') .set('Content-Type', 'text/plain') .write('tobi'); req.end(callback);
上面说起的高级api方法,能够通用.attach(name, [path], [filename])
和.field(name, value)
这两种形式来调用.添加多个附件也比较简单,只须要给附件提供自定义的文件名称,一样的基础名称也要提供.
request .post('/upload') .attach('avatar', 'path/to/tobi.png', 'user.png') .attach('image', 'path/to/loki.png') .attach('file', 'path/to/jane.png') .end(callback);
跟html的字段很像,你能够调用.field(name,value)
方法来设置字段,假设你想上传一个图片的时候带上本身的名称和邮箱,那么你能够像下面写的那样:
request .post('/upload') .field('user[name]', 'Tobi') .field('user[email]', 'tobi[@learnboost](/user/learnboost).com') .attach('image', 'path/to/tobi.png') .end(callback);
nodejs客户端自己就提供了压缩响应内容,因此你不须要作任何其它事情.
为了强迫缓冲res.text
这样的响应内容,能够调用req.buffer()
方法,想取消默认的文本缓冲响应像text/plain
,text/html
这样的,能够调用req.buffer(false)
方法
当缓冲res.buffered
标识提供了,那么就能够在一个回调函数里处理缓冲和没缓冲的响应.
.withCredentials()
方法能够激活发送原始cookie的能力,不过只有在Access-Control-Allow-Origin
不是一个通配符(*),而且Access-Control-Allow-Credentials
为’true’的状况下才行.
request .get('http://localhost:4001/') .withCredentials() .end(function(res){ assert(200 == res.status); assert('tobi' == res.text); next(); })
当发送错误时,superagent首先会检查回调函数的参数数量,当err
参数提供的话,参数就是两个,以下:
request .post('/upload') .attach('image', 'path/to/tobi.png') .end(function(err, res){ });
当省略了回调函数,或者回调只有一个参数的话,能够添加error
事件的处理.
request .post('/upload') .attach('image', 'path/to/tobi.png') .on('error', handle) .end(function(res){ });
注意:superagent默认状况下,对响应4xx和5xx的认为不是错误,例如当响应返回一个500或者403的时候,这些状态信息能够经过res.error
,res.status
和其它的响应属性来查看,可是没有任务的错误对象会传递到回调函数里或者emit
一个error
事件.正常的error
事件只会发生在网络错误,解析错误等.
当产生一个4xx或者5xx的http错误响应,res.error
提供了一个错误信息的对象,你能够经过检查这个来作某些事情.
if (res.error) { alert('oh no ' + res.error.message); } else { alert('got ' + res.status + ' response'); }
superagent是一个很是实用的http代理模块,推荐你们使用.