版本: v3.8.0
SuperAgent 英文使用指南
SuperAgent
SuperAgent是轻量级渐进式ajax API,相比于现有的请求API,它更加灵活,可读,且学习成本低。 同样它也适用于Node.js!
request
.post('/api/pet')
.send({ name: 'Manny', species: 'cat' })
.set('X-API-Key', 'foobar')
.set('Accept', 'application/json')
.then(function(res) {
alert('yay got ' + JSON.stringify(res.body));
});
测试文档
以下 测试文档 是由Mocha's "doc" 记录生成的,直接反映了测试套件。 这提供了额外的文档来源。
基础请求
请求可以通过调用 request
对象的适当方法来启动,然后调用.then()
(or .end()
or await
) 来发送请求,例如一个简单的GET请求:
request
.get('/search')
.then(function(res) {
// res.body, res.headers, res.status
})
.catch(function(err) {
// err.message, err.response
});
HTTP 方法也可以使用字符串:
request('GET', '/search').then(success, failure);
旧的回调依旧可以使用。 将 .then()
替换成 .end()
:
request('GET', '/search').end(function(err, res){
if (res.ok) {}
});
可以使用绝对URL。 在Web浏览器中,绝对URL只在服务器实现 CORS 的情况下才起作用。
request
.get('http://example.com/search')
.then(function(res) {
});
Node 客户端支持向 Unix域套接字 发送请求:
// pattern: https?+unix://SOCKET_PATH/REQUEST_PATH
// Use `%2F` as `/` in SOCKET_PATH
request
.get('http+unix://%2Fabsolute%2Fpath%2Fto%2Funix.sock/search')
.then(res => {
});
DELETE , HEAD , PATCH , POST , 和 PUT 请求方法依旧可以使用, 只需要修改一下方法名即可:
request
.head('/favicon.ico')
.then(function(res) {
});
DELETE 也可以被称为.del()
与旧的IE兼容,其中delete
是一个保留字。
HTTP 方法默认是 GET,所以下面的写法也是可以的:
request('/search', function(err, res){
});
设置 header 字段
设置标题字段很简单,用字段名和值调用 .set()
:
request
.get('/search')
.set('API-Key', 'foobar')
.set('Accept', 'application/json')
.then(callback);
你也可以传递一个对象来在一次调用中设置几个字段:
request
.get('/search')
.set({ 'API-Key': 'foobar', Accept: 'application/json' })
.then(callback);
GET
请求
.query()
方法接受对象,当与 GET 方法一起使用时,将形成一个查询字符串。 以下将拼接成/ search?query = Manny&range = 1..5&order = desc
这样的一个查询字符串。
request
.get('/search')
.query({ query: 'Manny' })
.query({ range: '1..5' })
.query({ order: 'desc' })
.then(function(res) {
});
或者用一个对象包裹:
request
.get('/search')
.query({ query: 'Manny', range: '1..5', order: 'desc' })
.then(function(res) {
});
.query()
方法同样可以接收字符串的形式:
request
.get('/querystring')
.query('search=Manny&range=1..5')
.then(function(res) {
});
或者如下这样:
request
.get('/querystring')
.query('search=Manny')
.query('range=1..5')
.then(function(res) {
});
HEAD
请求
对于 HEAD 请求你依旧可以使用 .query()
方法。下面的 .query()
参数将会拼接成 /users?email=joe@smith.com
。
request
.head('/users')
.query({ email: 'joe@smith.com' })
.then(function(res) {
});
POST
/ PUT
请求
一个典型的JSON POST 请求可能看起来有点像下面这样,我们适当地设置 Content-Type 头字段,并“写”一些数据,在这种情况下,只是一个JSON字符串。
request.post('/user')
.set('Content-Type', 'application/json')
.send('{"name":"tj","pet":"tobi"}')
.then(callback)
JSON无疑是最常见的,这就是 默认的 ! 下面的例子等同于前面的例子
request.post('/user')
.send({ name: 'tj', pet: 'tobi' })
.then(callback)
或调用多次 .send()
:
request.post('/user')
.send({ name: 'tj' })
.send({ pet: 'tobi' })
.then(callback)
默认情况下,发送字符串将把 Content-Type 设置为 application / x-www-form-urlencoded
,多个调用将与&
连接在一起,这里生成name = tj&pet = tobi
:
request.post('/user')
.send('name=tj')
.send('pet=tobi')
.then(callback);
SuperAgent 格式是可扩展的,但默认支持 "json" 和 "form"。 要以 application / x-www-form-urlencoded
方式发送数据,只需使用 "form" 调用 .type()
,默认为“json”。 这个请求将 POST 的 body拼接成“名称= tj&pet = tobi"。
request.post('/user')
.type('form')
.send({ name: 'tj' })
.send({ pet: 'tobi' })
.then(callback)
发送一个 FormData
格式的数据也是支持的。以下示例将 POST 标识为 id =“myForm” 的HTML表单的内容。
request.post('/user')
.send(new FormData(document.getElementById('myForm')))
.then(callback)
设置 Content-Type
.set()
方法也是经常使用的:
request.post('/user')
.set('Content-Type', 'application/json')
作为一个简短方式, .type()
方法也是可用的,它接受规范化的 MIME 类型名称完整的类型/子类型,或简单的扩展名称,如“xml”,“json”,“png”:
request.post('/user')
.type('application/json')
request.post('/user')
.type('json')
request.post('/user')
.type('png')
序列化请求正文
SuperAgent会自动序列化JSON和表单。 如果要以自定义格式发送有效内容,则可以使用 .serialize()
方法替换内置序列化。
重试请求
当给定 .retry()
方法时,SuperAgent 会自动重试请求,如果它们以短暂的失败或可能是由于Internet连接造成的。
此方法有两个可选参数:重试次数(默认值3)和回调。 它在每次重试之前调用 callback(err,res)
。 回调可能返回 true
/false
来控制请求是否被重试(但总是应用最大重试次数)。
request
.get('http://example.com/search')
.retry(2) // or:
.retry(2, callback)
.then(finished);
仅对 幂等 的请求使用 .retry()
。
设置 Accept
类似于 .type()
方法,也可以通过简短的方法 .accept()
来设置 Accept
头。request.types
还允许您指定完整的规范化 MIME 类型名称为type/subtype
,或者扩展后缀形式为“xml”,“json”,“png”:
request.get('/user')
.accept('application/json')
request.get('/user')
.accept('json')
request.post('/user')
.accept('png')
Facebook 和 Accept JSON
如果你正在调用 Facebook 的API,请确保在您的请求中发送 "Accept:application/json" 头。 如果你不这样做,Facebook 会用Content-Type:text / javascript; charset = UTF-8
,SuperAgent 将不会解析,因此 res.body
将是未定义的。 你可以用 req.accept('json')
或req.header('Accept','application / json')
来做到这一点。 有关详细信息,请参见 issues1078。
查询字符串
req.query(obj)
是一个可以用来建立一个查询字符串的方法。 例如,在 POST 上填充 ?format = json&dest = / login
:
request
.post('/')
.query({ format: 'json' })
.query({ dest: '/login' })
.send({ post: 'data', here: 'wahoo' })
.then(callback);
默认情况下,查询字符串不会以任何特定的顺序组装的。 asciibetically-sorted 排序的查询字符串可以用req.sortQuery()
来启用。 你也可以用 req.sortQuery(myComparisonFn)
提供一个自定义的排序比较函数。 比较函数应该带2个参数并返回一个负/零/正整数。
// default order request.get('/user') .query('name=Nick') .query('search=Manny') .sortQuery() .then(callback) // customized sort function request.get('/user') .query('name=Nick') .query('search=Manny') .sortQuery(function(a, b){ return a.length - b.length; }) .then(callback)
TLS 选项
在 Node.js 中,SuperAgent 支持配置 HTTPS 请求的方法:
.ca()
: 将CA证书设置为信任.cert()
: 设置客户端证书链.key()
: 设置客户端私钥.pfx()
: 设置客户端PFX或PKCS12编码的私钥和证书链
更多信息,请看 Node.js https.request docs.
var key = fs.readFileSync('key.pem'), cert = fs.readFileSync('cert.pem'); request .post('/client-auth') .key(key) .cert(cert) .then(callback);
var ca = fs.readFileSync('ca.cert.pem'); request .post('https://localhost/private-ca-server') .ca(ca) .then(res => {});
解析响应主体
SuperAgent 将为你解析已知的响应主体数据,目前支持 application / x-www-form-urlencoded
,application / json
和 multipart / form-data
。
您可以使用 .buffer(true).parse(fn)
方法设置自定义解析器(优先于内置解析器)。 如果没有启用响应缓冲 (.buffer(false)
),那么 response
事件将不会等待 body 解析完成,所以 response.body
将不可用。
JSON / Urlencoded
例如,如果请求用JSON字符串 “{”user“:{”name“:”tobi“}}” 响应,那么 res.body.user.name
就是解析对象就是“tobi”。同样,“user [name] = tobi”的x-www-form-urlencoded值也会产生相同的结果。 只支持一个嵌套级别。 如果您需要更复杂的数据,请发送JSON。
通过重复key发送数组。 .send({color:['red','blue']})
发送 color = red&color = blue
。 如果你想让数组 key 在它们的名字中包含[]
,你必须自己添加它,因为SuperAgent不会自动添加它。
Multipart
Node客户端通过 Formidable 模块支持 multipart / form-data 。 当解析多部分响应时,对象 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”对象。
二进制
在浏览器中,你可以使用 .responseType('blob')
来请求处理二进制响应主体。 在 node.js 中运行时,此API不是必要的。 这个方法支持的参数值是
blob
传递给 XmlHTTPRequestresponseType
属性arraybuffer' 传递给 XmlHTTPRequest
responseType` 属性
req.get('/binary.data') .responseType('blob') .end(function (error, res) { // res.body will be a browser native Blob type here });
更多内容请看 Mozilla Developer Network xhr.responseType docs。
响应属性
响应对象设置了许多有用的标志和属性,包括响应文本,解析的响应主体,标题字段,状态标志等等。
响应文本
res.text
属性包含未解析的响应正文字符串。 此属性始终为客户端API提供,并且仅当默认情况下mime类型与节点默认匹配“text / ”,“ / json”或“x-www-form-urlencoded”时。 其原因是为了节省内存,因为诸如多部分文件或图像的大型文本的缓存文本是非常低效的。 要强制缓存请参阅 “缓存响应” 部分。
响应体
与 SuperAgent 可以自动序列化请求数据一样,它也可以自动解析它。 当为 Content-Type 定义一个解析器时,它将被解析,默认包含 “application / json” 和 “application / x-www-form-urlencoded” 。 解析的对象然后可以通过 res.body
获得。
响应头字段
res.header
包含一个解析的头部字段的对象,和节点一样压缩字段名称。 例如 res.header ['content-length']
。
响应类型
Content-Type 响应头是特殊的,提供 res.type
,这是没有字符集(如果有的话)。 例如,“text / html; charset = utf8” 的 Content-Type 将提供“text / html”作为“res.type”,然后“res.charset”属性将包含“utf8”。
响应状态
响应状态标志有助于确定请求是否成功以及其他有用信息,从而使 SuperAgent 成为与 RESTful Web 服务交互的理想选择。 这些标志目前定义为:
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({deadline:ms})
或req.timeout(ms)
(其中ms
是毫秒数> 0)为整个请求(包括所有重定向)设置完成的最后期限.。如果在这段时间内没有完全下载响应,请求将被中止。req.timeout({response:ms})
设置等待来自服务器的第一个字节的最大时间, 但并不限制整个下载可以花费多长时间。响应超时应比服务器响应所需的时间要长数秒,因为它还包括进行DNS查找,TCP / IP和TLS连接的时间。
你应该使用 deadline
和 response
超时。 通过这种方式,你可以使用短暂的响应超时来快速检测到无响应的网络,并且可以在较慢的但可靠的网络上为下载提供时间。
request
.get('/big-file?network=slow')
.timeout({
response: 5000, // Wait 5 seconds for the server to start sending,
deadline: 60000, // but allow 1 minute for the file to finish loading.
})
.then(function(res) {
if (err.timeout) { /* timed out! */ }
});
超时错误具有 .timeout
属性。
认证
在 Node 和浏览器中,通过 .auth()
方法提供的 auth 可用:
request
.get('http://local')
.auth('tobi', 'learnboost')
.then(callback);
在 Node 客户端中,基本身份验证可以在URL中作为“user:pass”:
request.get('http://tobi:learnboost@local').then(callback);
默认情况下只使用 Basic
auth。 在浏览器中,你可以添加 `{type:'auto'} 来启用浏览器内置的所有方法(Digest,NTLM等):
request.auth('digest', 'secret', {type:'auto'})
重定向 (Following redirects)
默认情况下最多会有5个重定向,但是你可以用 res.redirects(n)
方法指定:
request
.get('/some.png')
.redirects(2)
.then(callback);
代理全局状态
保存cookies
在Node中,SuperAgent 默认不保存 cookie,但是你可以使用 .agent()
方法创建一个保存 cookie 的SuperAgent 副本。 每个副本都有一个单独的 cookie 。
const agent = request.agent();
agent
.post('/login')
.then(() => {
return agent.get('/cookied-page');
});
在浏览器中,Cookie 由浏览器自动管理,因此 .agent()
不会隔离cookie。
多个请求的默认选项
代理程序上调用的常规请求方法 (.use()
,.set()
,.auth()
)将用作该代理程序发出的所有请求的默认值。
const agent = request.agent()
.use(plugin)
.auth(shared);
await agent.get('/with-plugin-and-auth');
await agent.get('/also-with-plugin-and-auth');
管道数据
Node客户端允许您将数据传入和传出请求。 例如,传递一个文件的内容作为请求:
const request = require('superagent');
const fs = require('fs');
const stream = fs.createReadStream('path/to/my.json');
const req = request.post('/somewhere');
req.type('json');
stream.pipe(req);
请注意,当您管道请求时,superagent 会使用 chunked transfer encoding 发送管道数据,而不是所有服务器都支持(例如,Python WSGI服务器)。
或者将响应传递给一个文件:
const stream = fs.createWriteStream('path/to/my.json');
const req = request.get('/some.json');
req.pipe(stream);
请注意,您应该 不 尝试管道 .end()
或 Response
对象的结果:
// Don't do either of these:
const stream = getAWritableStream();
const req = request
.get('/some.json')
// this pipes garbage to the stream and fails in unexpected ways
.end((err, response) => response.pipe(stream))
const req = request
.get('/some.json')
.end()
// this is also unsupported, .pipe calls .end for you.
.pipe(stream);
在superagent的 未来版本 中,不正确地调用pipe()
将会失败。
多部分请求
SuperAgent 对于提供 .attach()
和 .field()
方法的 building 多部分请求也非常给力。
当你使用 .field()
或者 .attach()
时,你不能使用 .send()
而你 不能 设置 'Content-Type'(正确的类型将会被(自动)设置)。
发送文件
要发送文件,请使用 .attach(name, [file], [options])
。 您可以通过多次调用 .attach
来附加多个文件。 参数是:
name
— 表单字段名称file
— 带有文件路径的字符串或者“Blob”/“Buffer”对象options
— (可选) 用自定义文件名字符串或者“{filename:string}”对象。 在Node中,还支持{contentType:'mime / type'}
。 在浏览器中,用相应的类型创建一个“Blob”。
request
.post('/upload')
.attach('image1', 'path/to/felix.jpeg')
.attach('image2', imageBuffer, 'luna.jpeg')
.field('caption', 'My cats')
.then(callback);
字段值
就像HTML中的表单字段一样,你可以用 .field(name,value)
和 .field({name:value})
来设置字段值。 假设你想用你的名字和电子邮件上传几张图片,你的请求可能是这样的:
request
.post('/upload')
.field('user[name]', 'Tobi')
.field('user[email]', 'tobi@learnboost.com')
.field('friends[]', ['loki', 'jane'])
.attach('image', 'path/to/tobi.png')
.then(callback);
压缩
节点客户端支持压缩响应,最重要的是,你不必做任何事情!它能用。
缓存响应
要强制缓存响应主体为 res.text
,你可以调用 req.buffer()
。 要撤消文本响应的默认缓存,例如 “text / plain”,“text / html”等,你可以调用 req.buffer(false)
。
当缓冲提供 res.buffered
标志时,你可以使用它来处理同一个回调中的缓存和无缓存响应。
CORS
出于安全原因,浏览器将阻止跨源请求,除非服务器选择使用CORS标头。 浏览器也会做额外的
OPTIONS 请求来检查服务器允许的HTTP头和方法。 阅读更多关于CORS。
The .withCredentials()
method enables the ability to send cookies from the origin, however only when Access-Control-Allow-Origin
is not a wildcard (""), and Access-Control-Allow-Credentials
is "true".
.withCredentials()
方法使得能够从源站发送cookie,但是只有当'Access-Control-Allow-Origin'不是通配符(“”)和Access-Control-Allow-Credentials
是 "true”时。
request
.get('http://api.example.com:4001/')
.withCredentials()
.then(function(res) {
assert.equal(200, res.status);
assert.equal('tobi', res.text);
})
错误处理
你的回调函数将始终传递两个参数:错误和响应。 如果没有错误发生,第一个参数将为null:
request
.post('/upload')
.attach('image', 'path/to/tobi.png')
.then(function(res) {
});
当你监听的时候,"error" 事件将被触发:
request
.post('/upload')
.attach('image', 'path/to/tobi.png')
.on('error', handle)
.then(function(res) {
});
请注意,superagent默认考虑 4xx 和 5xx 响应(以及未处理的 3xx 响应)错误。 例如,如果你得到一个304 Not modified
,403 Forbidden
或500 Internal server error
的响应,这个状态信息可以通过err.status
获得。 来自这样的响应的错误还包含具有在 “响应属性”
中提及的所有属性的“err.response”字段。 库以这种方式处理想要成功响应和将HTTP错误状态码视为错误的常见情况,同时仍允许围绕特定错误条件的定制逻辑。
网络故障,超时以及其他不产生响应的错误将不包含“err.status”或“err.response”字段。
如果你希望处理404或其他HTTP错误响应,则可以查询“err.status”属性。 当发生HTTP错误(4xx或5xx响应)时,res.error
属性是一个Error
对象,这允许你执行如下检查:
if (err && err.status === 404) {
alert('oh no ' + res.body.message);
}
else if (err) {
// all other error types we handle generically
}
或者,您可以使用.ok(callback)
方法来决定响应是否是错误的。 如果响应应该被解释为成功,则对“ok”函数的回调将得到一个响应并返回“true”。
request.get('/404')
.ok(res => res.status < 500)
.then(response => {
// reads 404 page as a successful response
})
进度跟踪
SuperAgent在上传和下载大文件时触发“progress”事件。
request.post(url)
.attach('field_name', file)
.on('progress', event => {
/* the event is:
{
direction: "upload" or "download"
percent: 0 to 100 // may be missing if file size is unknown
total: // total file size, may be missing
loaded: // bytes downloaded or uploaded so far
} */
})
.end()
Promise 和 Generator 支持
SuperAgent 的请求是一个“可接受的”对象,它与 JavaScript promise 和 async
/await
语法兼容。 如果你使用promises,请勿调用 .end()
。
像 co 这样的库或 koa 这样的 web 框架可以在任何 SuperAgent 方法上 "yield" :
const req = request
.get('http://local')
.auth('tobi', 'learnboost');
const res = yield req;
请注意,SuperAgent 期望全局 Promise
对象存在。 您需要在 Internet Explorer 或 Node.js 0.10 中使用 polyfill 来使用 promise 。
浏览器和节点版本
SuperAgent 有两个实现:一个用于Web浏览器(使用XHR),一个用于Node.JS(使用核心http模块)。 默认情况下,Browserify和WebPack将选择浏览器版本。
如果要使用WebPack编译Node.JS的代码,您必须在其配置中指定node target。
在 electron 中使用浏览器版本
Electron 开发人员报告,如果您希望使用浏览器版本的 SuperAgent 而不是Node版本,则可以使用 require('superagent / superagent')
。 您的请求现在将显示在Chrome开发人员工具“网络”标签中。 请注意,此环境不包含在自动化测试套件中,并且不受官方支持。