SuperAgent
SuperAgent是輕量級更為優(yōu)化的ajax API黎泣,對比大量糟糕的現(xiàn)存的API绊含,SuperAgent是靈活的剩失、易讀的屈尼、并且非常易學(xué)册着,同時SuperAgent可用于Node.js!
request
.post('/api/pet')
.send({ name: 'Manny', species: 'cat' })
.set('X-API-Key', 'foobar')
.set('Accept', 'application/json')
.end(function(err, res){
if (err || !res.ok) {
alert('Oh no! error');
} else {
alert('yay got ' + JSON.stringify(res.body));
}
});
原文地址
http://visionmedia.github.io/superagent/#buffering-responses
測試文檔
以下測試文檔是使用Mocha的"doc" reporter生成的脾歧,并且直接反映測試套件甲捏,這提供一種文檔的額外資源。
基本請求
初始化一個請求可以通過調(diào)用request模塊中適當?shù)姆椒ū拗矗缓笫褂?code>.end()來發(fā)送請求摊鸡,例如一個簡單的GET請求:
request
.get('/search')
.end(function(err, res){
});
一個方法字符串也是允許的:
request('GET', '/search').end(callback);
支持ES6蚕冬,可以使用.then()
來代替.end()
request('GET', '/search').then(success, failure);
Node客戶端也許提供絕對urls:
request
.get('http://example.com/search')
.end(function(err, res){
});
DELETE, HEAD, POST, PUT以及其他HTTP請求都可使用免猾,只需要簡單的改變方法名稱:
request
.head('/favicon.ico')
.end(function(err, res){
});
DELETE是特殊的保留字段,方法命名為.del()
:
request
.del('/user/1')
.end(function(err, res){
});
HTTP方法默認為GET囤热,如果你想如此猎提,以下示例是有效的:
request('/search', function(err, res){
});
設(shè)置頭字段
設(shè)置頭字段是簡單的,使用字段名稱和值來調(diào)用.set()
:
request
.get('/search')
.set('API-Key', 'foobar')
.set('Accept', 'application/json')
.end(callback);
你也可以在一個簡單請求中通過傳遞一個對象來設(shè)置一些字段:
request
.get('/search')
.set({'API-Key': 'foobar', Accept: 'application/json'})
.end(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' })
.end(function(err, res){
});
或使用一個簡單對象:
request
.get('/search')
.query({ query: 'Manny', range: '1..5', order: 'desc' })
.end(function(err, res){
});
.query()
方法也接受字符串:
request
.get('/querystring')
.query('search=Manny&range=1..5')
.end(function(err, res){
});
或連接:
request
.get('/querystring')
.query('search=Manny')
.query('range=1..5')
.end(function(err, res){
});
HEAD請求
你也可以使用.query()
方法來進行HEAD請求棺聊,以下示例將生成路徑/users?email=joe@smith.com
request
.head('/users')
.query({ email: 'joe@smith.com' })
.end(function(err, res){
});
POST/PUT請求
一個典型的JSON POST請求有點像以下示例伞租,我們適當?shù)脑O(shè)置Content-Type頭字段,并且"寫"一些數(shù)據(jù)限佩,在此時只是一個JSON字符串
request
.post('/user')
.set('Content-Type', 'application/json')
.send('{"name":"tj","pet":"tobi"}')
.end(callback)
JSON無疑是使用最多的,它也是默認的葵诈!以下示例與之前的相同
request
.post('/user')
.send({ name: 'tj', pet: 'tobi' })
.end(callback)
或使用多個.send()
請求:
request.post('/user')
.send({ name: 'tj' })
.send({ pet: 'tobi' })
.end(callback)
默認發(fā)送字符串將設(shè)置Content-Type為application/x-www-form-urlencoded
,多個請求將使用&
連接,這里結(jié)果是name=tj&pet=tobi
:
request.post('/user')
.send('name=tj')
.send('pet=tobi')
.end(callback);
SuperAgent格式是可擴展的祟同,但支持默認"json"和"form"作喘,發(fā)送類似application/x-www-form-urlencoded
的數(shù)據(jù)只需要調(diào)用"form"的.type()
,這里默認是"json",這種請求將會POST"name=tj&pet=tobi"
request.post('/user')
.type('form')
.send({ name: 'tj' })
.send({ pet: 'tobi' })
.end(callback)
Note:"form"別名為"form-data"和"urlencoded"并后向相容
設(shè)置Content-Type
之前的結(jié)論是使用.set()
方法
request.post('/user')
.set('Content-Type', 'application/json')
.type()
方法也可用于速記晕城,接受規(guī)范化使用type/subtype完成的MIME類型名稱泞坦,或簡單的擴展名稱例如"xml","json","png"等等:
request.post('/user')
.type('application/json')
request.post('/user')
.type('json')
request.post('/user')
.type('png')
序列化請求結(jié)構(gòu)
SuperAgent會自動序列化JSON和格式,如果你想要再一個傳統(tǒng)格式下發(fā)送一個有效載荷砖顷,你可以使用.serialize()
方法替換內(nèi)置序列化
設(shè)置接收
通過速記方法.accept()
設(shè)置接收頭可以達成與.type()
方法類似的效果贰锁,參考request.types
允許你指定類似type/subtype的完全規(guī)范化MIME名稱,或延期后綴格式類似"xml"滤蝠、"json"豌熄、"png":
request.get('/user')
.accept('application/json')
request.get('/user')
.accept('json')
request.post('/user')
.accept('png')
查詢字符串
res.query(obj)
方法可被用于建立一個查詢字符串,例如在一個POST中填充?format=json&dest=/login
request
.post('/')
.query({ format: 'json' })
.query({ dest: '/login' })
.send({ post: 'data', here: 'wahoo' })
.end(callback);
解析返回結(jié)構(gòu)
SuperAgent將解析已知的返回結(jié)構(gòu)數(shù)據(jù)給你几睛,當前支持application/x-www-form-urlencoded
,application/json
和multipart/form-data
.
你可以使用.buffer(true).parse(fn)
方法設(shè)置自定義解析(提升優(yōu)先級高于建立解析)房轿,如果返回緩沖不可用(.buffer(false)
),response
事件將發(fā)出而不會等待結(jié)構(gòu)解析器結(jié)束,因此response.body
將不可用
JSON/Urlencoded
res.body
屬性是解析對象囱持,例如如果一個請求返回JSON字符串'{"user":{"name":"tobi"}}'夯接,res.body.user.name
將變?yōu)?tobi",同樣"user[name]=tobi"的x-www-form-urlencoded值將產(chǎn)生同樣的結(jié)果
Multipart
Node客戶端通過Formidable模塊支持multipart/form-data,當解析multipart返回時,對象res.files
對你也是可用的纷妆,假設(shè)例如一個請求響應(yīng)如下multipart結(jié)構(gòu):
--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
對象包含磁盤地址、文件名掩幢、和其他屬性
響應(yīng)屬性
很多有用的標志和屬性設(shè)置在Response
對象逊拍,范圍包括返回文本、解析返回結(jié)構(gòu)际邻、頭字段芯丧、狀態(tài)標志等
返回文本
res.text
屬性包含未解析返回結(jié)構(gòu)字符串,這個屬性會一直由客戶端API提供世曾,并且僅當mime類型匹配"text/"缨恒、"/json"或"x-www-form-urlencoded"默認為節(jié)點時,這是為了保存記憶轮听,大型結(jié)構(gòu)體的緩存文本骗露,例如multipart文件或圖片的效率是非常低的。
強制緩存可查看"緩存返回"部分
返回部分
類似SuperAgent可以自動序列化請求數(shù)據(jù)血巍,SuperAgent也可以解析它萧锉,當一個解析器定義Content-Type,他的解析方式默認包含"application/json"和"application/x-www-form-urlencoded"述寡。解析對象通過res.body
可用
返回頭字段
res.header
包含一個細節(jié)頭字段的對象柿隙,小寫字段名如節(jié)點一致,例如res.header['content-length']
返回Content-Type
Content-Type返回頭是特殊情況辨赐,提供res.type
优俘,這是字符集的void(如果有的話),例如Content-Type值為"text/html; charset=utf8"將提供res.type
值為"text/html",res.charset
屬性將包含"utf8"掀序。
返回狀態(tài)
返回狀態(tài)標志幫助決定請求是否成功、包含其他有用的信息惭婿,使得SuperAgent更理想的與RESTful web服務(wù)互動不恭,這些標志當前定義如下:
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;
中止請求
中止請求簡單調(diào)用req.abort()
方法
請求超時
通過調(diào)用req.timeout(ms)
可應(yīng)用超時,調(diào)用之后錯誤將會觸發(fā)财饥,為區(qū)分其他錯誤换吧,err.timeout
屬性設(shè)置為ms
值。NOTE這是一個超時應(yīng)用于請求和所有重定向钥星,而不是對應(yīng)每次請求
驗證
在所有Node和瀏覽器通過.auth()
方法可用auth:
request
.get('http://local')
.auth('tobi', 'learnboost')
.end(callback);
在Node客戶端基礎(chǔ)auth可在URL中"user:pass"字段:
request.get('http://tobi:learnboost@local').end(callback);
默認只有Basic
auth可用沾瓦,在瀏覽器你可以添加{type:'auto'}
來確保所有方法在瀏覽器(Digest、NTLM等)中建立
request.auth('digest', 'secret', {type:'auto'})
Following重定向
默認超過5個重定向?qū)⒈籪ollowed,但是你可以使用res.redirects(n)
方法來指定:
request
.get('/some.png')
.redirects(2)
.end(callback);
Piping數(shù)據(jù)
Node客戶端允許你在請求中pipe傳入傳出數(shù)據(jù)贯莺,例如piping文件的內(nèi)容作為請求:
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);
或piping返回到一個文件:
var request = require('superagent') ,
fs = require('fs');
var stream = fs.createWriteStream('path/to/my.json');
var req = request.get('/some.json');
req.pipe(stream);
Multipart 請求
SuperAgent也適用于建立multipart請求风喇,為此提供了.attach()
和.field()
方法
附屬文件
如上所述,提供了一種更高級別的API缕探,格式為.attach(name, [path], [filename])
和.field(name, value)
魂莫。附屬幾個文件很簡單,你可以提供一個定制文件名作為附屬爹耗,除非附屬文件的基礎(chǔ)名已經(jīng)被使用了
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)
設(shè)置字段值,假設(shè)你想上傳一些圖片以及你的名字和email潭兽,你的請求可以像下面這樣:
request
.post('/upload')
.field('user[name]', 'Tobi')
.field('user[email]', 'tobi@learnboost.com')
.attach('image', 'path/to/tobi.png')
.end(callback);
壓縮
node客戶端支持壓縮返回倦始,最好你不需要做任務(wù)事,它本身在工作中
緩沖返回
為了強制返回結(jié)構(gòu)緩沖為res.text
山卦,你可以調(diào)用req.buffer()
楣号,你可以調(diào)用req.buffer(false)
來撤銷默認緩存文本返回,例如"text/plain"怒坯,"text/html"等炫狱。
當res.buffered
標志緩存已提供,你可以使用這個來處理在相同回調(diào)中的緩存或未緩存返回
CORS
.withCredentials
方法確碧拊常可以發(fā)送cookies视译,但僅有當"Access-Control-Allow-Origin"不是通配符時("*"),"Access-Control-Allow-Credent-ials"為"true"
request
.get('http://localhost:4001/')
.withCredentials()
.end(function(err, res){
assert(200 == res.status);
assert('tobi' == res.text);
next();
})
錯誤處理
你的回調(diào)函數(shù)始終傳遞兩個參數(shù):錯誤和返回归敬,如果沒有錯誤發(fā)送酷含,第一個參數(shù)為空:
request
.post('/upload')
.attach('image', 'path/to/tobi.png')
.end(function(err, res){
});
An "error" event is also emitted, with you can listen for:
request
.post('/upload')
.attach('image', 'path/to/tobi.png')
.on('error', handle)
.end(function(err, res){
});
注意4xx或5xx的超級代理返回默認為錯誤,例如你獲取一個500或403返回汪茧,使用err.status
可使用這個狀態(tài)信息椅亚,這種返回錯誤頁包含了一個err.response
字段,它有著"Response properties"中所有的上述狀態(tài)舱污。
網(wǎng)絡(luò)失敗呀舔,超時,和其他錯誤產(chǎn)生無返回將不包含err.status
或err.response
字段扩灯。
如果你處理404或其他HTTP錯誤返回媚赖,你可以查詢err.status
屬性,當一個HTTP錯誤發(fā)生(4xx或5xx返回)珠插,res.error
屬性石一個Error
對象惧磺,這允許你像這樣執(zhí)行檢查:
if (err && err.status === 404) {
alert('oh no ' + res.body.message);
}
else if (err) {
// all other error types we handle generically
}
Promise and Generator support
SuperAgent的請求是一個"thenable"對象,它兼容JavaScript語法和async
/await
句法捻撑。
類似co或koa可以在任何SuperAgent方法中產(chǎn)生:
var res = yield request
.get('http://local')
.auth('tobi', 'learnboost')
注意SuperAgent期望呈現(xiàn)全局Promise
對象磨隘,在Internet Explorer或Node.js 0.10中你將需要一個polyfill來使用promises缤底。
Facebook和接受JSON
如果你請求了Facebook的API,確保在你的請求中發(fā)送一個Accept: application/json
頭番捂,如果你不想這樣做个唧,F(xiàn)acebook會返回Content-Type: text/javascript: charset=UTF-8
,SuperAgent將不會解析并且res.body
將不會定義白嘁,你可以使用req.accept('json')
或req.header('Accept', 'application/json')
坑鱼。
瀏覽器和node版本
SuperAgent有兩個實現(xiàn):一個給瀏覽器(使用XHR),一個給Node.JS(使用核心http模板)絮缅,默認Browserity和WebPack將采用瀏覽器版本
如果你想要使用WebPack來編譯Node.JS代碼鲁沥,你必須在它的配置中指定node目標
在electron中使用瀏覽器版本
Electron開發(fā)者報告如果你使用SuperAgent的瀏覽器版本而不是Node版本時,你可以require('superagent/superagent')
耕魄,你的請求將不會在Chrome開發(fā)者工具中表現(xiàn)出來画恰,注意這個環(huán)境不被自動化測試包含斌并且不是正式支持的