SuperAgent使用文件
本篇文件是參考SuperAgent英文文件翻譯整理成的。前段時間,在一個爬蟲專案中用到了SuperAgent,因為遇到了一些坑,就詳細的查閱了一下官方的文件,為了便於其他朋友查閱參考,我便對翻譯的文件進行了簡要整理。後期,我還會針對SuperAgent使用中遇到的一些問題進行完善,並附於文末Issue章節。同時也歡迎大家分享自己在使用SuperAgent過程中遇到的一些問題和解決方法。
1 簡介
SuperAgent是一個輕量級、靈活的、易讀的、低學習曲線的客戶端請求代理模組,使用在NodeJS環境中。
官方文件:
使用示例:
var request = require('superagent') request .post('/api/pet') .send({ name: 'Manny', species: 'cat' }) .set('X-API-Key', 'foobar') .set('Accept', 'application/json') .then(res => { alert('yay got ' + JSON.stringify(res.body)); });
在後面的講解中我們都使用request
表示superagent
物件,程式碼中也省略如下部分:
var request = require('superagent')
2 請求
透過呼叫request
物件then()
或end()
方法,或使用await
關鍵字,傳送一個請求。
request .get('/search') .then(res => { // res.body, res.headers, res.status }) .catch(err => { // err.message, err.response });
請求的方法型別(DELETE
,HEAD
,PATCH
,POST
和PUT
)可以透過如下字串來指定:
// 指定使用GET方法request('GET', '/search') .then(function (response) { // success }, function (error) { // failure});
也可以使用end()
方法
request('GET', '/search') .end(function(error, response){ if (response.ok) { } });
可以使用完整的URLs,由於同源策略的原因,這需要伺服器實現了跨域訪問。
request .get('') .then(res => { });
除了上述使用的GET
方法外,也可以使用DELETE
,HEAD
,PATCH
,POST
和PUT
方法,只需要簡單地更改一下方法的名稱。
request .head('/favicon.ico') .then(response => { });
在舊版本IE瀏覽器中delete
是系統的關鍵字,為了相容這一點,可以呼叫del()
方法來避免衝突。
request .del('/book/1') .end(function(response){ });
request
預設使用GET方法傳送請求,可以簡寫成如下:
request('/search', (error, response) => { });
3 HTTP/2
如果要使用HTTP/2協議傳送請求,可以呼叫http2()
方法。目前還暫不支援對伺服器 HTTP/2能力的檢測。
const request = require('superagent');const res = await request .get('') .http2();
4 設定頭部欄位
報文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);
5 GET請求
當我們使用GET請求傳遞查詢字串的時候,可以使用query()
方法,同時傳遞一個物件作為引數,下面的程式碼將產生一個URL為/search?query=Manny&range=1..5&order=desc
請求:
request .get('/search') .query({ query: 'Manny' }) .query({ range: '1..5' }) .query({ order: 'desc' }) .then(response => { });
或者傳遞一個物件
request .get('/search') .query({ query: 'Manny', range: '1..5', order: 'desc' }) .then(response => { });
query()
也接受一個字串作為引數
request .get('/querystring') .query('search=Manny&range=1..5') .then(response => { })
引數拼接字元&
也可以用下面的方式替代:
request .get('/querystring') .query('search=Manny') .query('range=1..5') .then(response => { });
6 HEAD請求
query()
方法也可以用於HEAD請求,下面的程式碼將會產生一個URL為 /users?email=joe@smith.com
的請求:
request .head('/users') .query({ email: 'joe@smith.com' }) .then(response => { });
7 POST / PUT請求
一個典型的JSON POST請求的程式碼實現如下,設定相應的Content-type頭欄位,再寫入資料。在這個例子裡,僅使用JSON字串:
request.post('/user') .set('Content-Type', 'application/json') .send('{"name":"tj","pet":"tobi"}') .then(callback)
JSON成為通用的資料格式後,request
物件預設Content-type型別就是application/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
,多次呼叫send()
方法會使用&
連線起來,下面的程式碼中最終結果為:name=tj&pet=tobi
request.post('/user') .send('name=tj') .send('pet=tobi') .then(callback);
SuperAgent請求的資料格式是可以擴充套件的,不過預設支援“form”和“json”兩種格式,想要以application/x-www-form-urlencoded格式傳送資料的話,則可以呼叫type()
方法並傳入'form'
引數,這裡預設的引數是“json”。下面的請求中,POST請求體為name=tj&pet=tobi
。
request.post('/user') .type('form') .send({ name: 'tj' }) .send({ pet: 'tobi' }) .then(callback)
支援傳送FormData
物件。下面的例子中傳送id="myForm"
的表單資料:
request.post('/user') .send(new FormData(document.getElementById('myForm'))) .then(callback)
提示:FormData
型別其實是在XMLHttpRequest 2級定義的,它是為序列化表以及建立與表單格式相同的資料(當然是用於XHR傳輸)提供便利。
8 Content-Type設定
通常使用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')
9 序列化請求體
SuperAgent會自動序列化JSON和表單資料,你也可以為其他型別設定自動序列化:
request.serialize['application/xml'] = function (obj) { return 'string generated from obj'; };// going forward, all requests with a Content-type of// 'application/xml' will be automatically serialized
如果你希望以自定義格式傳送資料,可以透過.serialize()
方法為每個請求設定相應的序列化方法,以替換內建序列化方法:
request .post('/user') .send({foo: 'bar'}) .serialize(obj => { return 'string generated from obj'; });
10 重發請求
當給定retry()
方法時,SuperAgent將自動重試請求,如果它們以短暫的方式失敗或者可能由於因特網連線不正常而失敗。
這個方法有兩個可選引數:重試次數(預設值3)和回撥函式。它在每次重發之前呼叫回撥(error, res)
。回撥可以返回true/false
,以決定是否要重發請求。
request .get('') .retry(2) // or: .retry(2, callback) .then(finished);
需要注意的是:應該只對HTTP等冪請求使用retry()
方法(即,到達伺服器的多個請求不會導致不希望的副作用,如重複購買,否則會產生多個訂單)。
11 設定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和接收JSON:如果你是在呼叫Facebook的API,確保請求頭中Accept: application/json
。否則,Facebook 將返回Content-Type: text/javascript; charset=UTF-8
響應, SuperAgent將不會解析這個響應,讀取響應體會得到undefined
。你需要在請求物件request
加上request.accept('json')
或者request.header('Accept', 'application/json')
程式碼。
12 查詢字串
呼叫.query()方法可以自動生成查詢字串,比如向URL為?format=json&dest=/login
傳送一個post請求:
request .post('/') .query({ format: 'json' }) .query({ dest: '/login' }) .send({ post: 'data', here: 'wahoo' }) .then(callback);
預設情況下,查詢字串的拼裝是沒有特定的順序。呼叫sortQuery()
方法將預設按照ASCII碼順序進行,你也可以傳遞一個比較函式來指定排序規則,比較函式需要傳遞兩個引數(在回撥過程中會自動傳遞進兩個引數,這兩個引數就是用於比較的查詢字串),返回值是正整數、負整數或者0。
// 選擇預設排序request.get('/user') .query('name=Nick') .query('search=Manny') .sortQuery() .then(callback)// 客製化的排序函式request.get('/user') .query('name=Nick') .query('search=Manny') .sortQuery((a, b) => a.length - b.length) .then(callback)
上述客製化的排序函式中,a
和b
實際上就是sortQuery()
回撥過程中傳遞進去的兩個查詢字串,按照查詢字串長度來排序的,長度大的排在前面。
13 TLS選項
在Node.js中使用SuperAgent,支援對HTTPS請求的下列配置:
ca()
:將CA證照設定為信任cert()
:設定客戶端證照鏈key()
: 設定客戶端私鑰pfx()
: 設定客戶端PFX或PKCS12編碼的私鑰和證照鏈
更多資訊可以檢視:.
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('') .ca(ca) .then(res => {});
14 解析響應體
SuperAgent 可以解析常用的響應體,目前支援application/x-www-form-urlencoded
,application/json
, 和multipart/form-data
格式。如下程式碼,你也可以對其它型別的響應體設定相應的解析方法:
// 瀏覽器端使用SuperAgentrequest.parse['application/xml'] = function (str) { return {'object': 'parsed from str'}; };// Node中使用SuperAgentrequest.parse['application/xml'] = function (res, cb) { // 解析響應內容,設定響應體程式碼 cb(null, res); };// 自動解析響應體
透過呼叫buffer(true)
和parse(fn)
的配合,你可以設定一個定製的解析器(定製的解析器優先於內建解析器)。 如果沒有啟用響應緩衝(buffer(false)
),那麼響應事件的觸發將不會等待主體解析器完成,因此響應體將不可用。
14.1 JSON/Urlencoded
response.body
是解析後的內容物件,比如對於一個請求響應'{"user":{"name":"tobi"}}'
字串,response.body.user.name
會返回"tobi"
。同樣的,與x-www-form-urlencoded
格式的"user[name]=tobi"
解析後值也是一樣,只支援巢狀的一個層次,如果需要更復雜的資料,請使用JSON格式。
陣列會以重複鍵名的方式進行傳送,send({color: ['red','blue']})
會傳送"color=red&color=blue"
。如果你希望陣列鍵的名稱包含"[]"
,則需要自己新增,SuperAgent是不會自動新增。
14.2 Multipart
Node客戶端透過模組來支援multipart/form-data
型別,當解析一個multipart
響應時,response.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
物件,包括一個磁碟檔案路徑、檔名稱,還有其它的檔案屬性。
14.3 Binary
在瀏覽器中可以使用responseType('blob')
來請求處理二進位制格式的響應體。在Node.js中執行此API是不必要的。此方法的支援引數值為:
'blob'
:會被傳遞為XmlHTTPRequest
的responseType
屬性。'arraybuffer'
:會被傳遞為XmlHTTPRequest
的responseType
屬性。
req.get('/binary.data') .responseType('blob') .then(res => { // res.body will be a browser native Blob type here });
更多的資訊可以檢視:.
15 響應物件屬性
SuperAgent請求得到響應後,響應物件的屬性主要有:
text
:未解析前的響應內容,字串型別。一般只在mime
型別能夠匹配"text/"
,"json"
,"x-www-form-urlencoding"
的情況下,這個屬性才會有效,預設為nodejs客戶端提供;body
:響應資料解析後的物件,物件型別。header
:解析之後的響應頭資料,陣列型別。type
:響應報文的Content-Type
值,字串型別。charset
:響應的字符集,字串型別。status
:響應狀態標識。statusCode
:響應的狀態碼,數整數型別。如:200、302、404、500等。
15.1 text
response.text
包含未解析前的響應內容,一般只在mime
型別能夠匹配"text/"
,"json"
,"x-www-form-urlencoding"
的情況下,這個屬性才會有效,預設為nodejs客戶端提供,這是出於節省記憶體的考慮。因為緩衝大資料量的文字(如multipart檔案或影像)的效率非常低。要強制緩衝,請參閱“響應緩衝”部分。
15.2 body
與SuperAgent請求資料自動序列化一樣,響應資料也會自動的解析,當為一個Content-Type
定義一個解析器後,就能自動解析,預設解析包含application/json
和application/x-www-form-urlencoded
,可以透過response.body
來訪問解析物件.
15.3 header fields
response.header包含解析之後的響應頭資料,欄位值都是Node處理成小寫字母形式,如response.header['content-length']
。
15.4 Content-Type
Content-Type
響應頭欄位是一個特列,伺服器提供response.type
來訪問它,預設response.charset
是空的(如果有的話,則為指定型別),例如Content-Type
值為"text/html; charset=utf8"
,則response.type
為text/html
,response.charset
為"utf8"
。
15.5 status
響應狀態標識可以用來判斷請求是否成功,除此之外,可以用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;
16.中止請求
可以透過req.abort()
來中止請求。
17.請求超時
有時網路和伺服器會“卡住”,並且在接受請求後從不響應。設定超時以避免請求永遠等待。
req.timeout({deadline:ms})
或req.timeout(ms)
: ms是大於0的毫秒數。為整個請求設定一個截止時間(包括所有上傳、重定向、伺服器處理時間)完成。如果在那個時間內沒有得到完整的響應,請求將被中止。req.timeout({response:ms})
:設定等待第一個位元組從伺服器到達的最大時間,但不限制整個下載可以消耗多長時間。響應超時應該比伺服器響應的時間長至少幾秒鐘,因為它還包括進行DNS查詢、TCP/IP和TLS連線的時間,以及上傳請求資料的時間。
你應該同時使用deadline
和response
超時。透過這種方式,你可以透過較短的response
超時來快速檢測無響應網路,並且使用較長的deadline
來在緩慢但可靠的網路上提供一個合適的時間。注意,這兩個計時器都限制了上傳檔案的上傳時間。如果上傳檔案,則使用長時間超時。
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(res => { /* responded in time */ }, err => { if (err.timeout) { /* timed out! */ } else { /* other error */ } });
超時錯誤會提供一個timeout
屬性。
18.認證
Node和瀏覽器中都可以透過auth()
方法來完成認證。
request .get('') .auth('tobi', 'learnboost') .then(callback);
nodejs客戶端也可以透過傳遞一個像下面這樣的URL:
request.get('').then(callback);
預設在瀏覽器中只使用基本的認證方式,你也可以新增{type:'auto'}
,以啟用瀏覽器中內建的所有方法(摘要、NTLM等):
request.auth('digest', 'secret', {type:'auto'})
19.跟隨重定向
預設是向上跟隨5個重定向,可以透過呼叫.res.redirects(n)來設定個數:
request .get('/some.png') .redirects(2) .then(callback);
20.全域性狀態代理
20.1 儲存cookies
在Node SuperAgent中,預設情況下不儲存cookie,但是可以使用.agent()方法建立一個含有cookie的SuperAgent副本。每個副本都有一個單獨的cookie資料。
const agent = request.agent(); agent .post('/login') .then(() => { return agent.get('/cookied-page'); });
在瀏覽器中,cookie由瀏覽器自動管理,因此.agent()
不會格式化處理cookies。
20.2 多請求的預設選項
使用agent
進行的多個請求中,agent
呼叫的常規方法也將預設用於agent
的後續所有的請求中。這些常規方法包括:use
, on
, once
, set
, query
, type
, accept
, auth
, withCredentials
, sortQuery
, retry
, ok
, redirects
, timeout
, buffer
, serialize
, parse
, ca
, key
, pfx
, cert
。
const agent = request.agent() .use(plugin) .auth(shared);await agent.get('/with-plugin-and-auth');await agent.get('/also-with-plugin-and-auth');
21.管道資料
在nodejs客戶端中,可以使用一個請求流來傳輸資料。需要注意的是:用pipe()
取代了end()
和then()
方法。
下面是將檔案內容作為請求進行管道傳輸例子:
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使用分塊傳輸編碼傳送管道資料,這不是所有伺服器(例如Python WSGI伺服器)都支援的。
下面是輸送一個響應流到檔案的管道傳輸例子:
const stream = fs.createWriteStream('path/to/my.json');const req = request.get('/some.json'); req.pipe(stream);
不能將管道、回撥或promise
混合在一起使用,不能嘗試對end()
或response
物件進行管道操作(pipe()
),如下所示:
// 不能做下面的操作const stream = getAWritableStream();const req = request .get('/some.json') // BAD: this pipes garbage to the stream and fails in unexpected ways .end((err, this_does_not_work) => this_does_not_work.pipe(stream))const req = request .get('/some.json') .end() // BAD: this is also unsupported, .pipe calls .end for you. .pipe(nope_its_too_late);
22.Multipart/form-data請求
superagen提供了attach()
和 field()
方法用於構建multipart/form-data請求。
當你使用了field()
或者attach()
,你就不能使用 send()
方法,你也不能設定 Content-Type (superagen會自動設定糾正後的type
)。
22.1 附件
可以使用attach(name, [file], [options])
進行檔案傳送。你可以透過多次呼叫attach()
附加多個檔案。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);
22.2 欄位值
與HTML中表單的欄位類似,你可以呼叫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);
23.壓縮
NodeJS客戶端本身就提供壓縮響應內容,所以你不需要做任何其它處理。
24.響應緩衝
為了強制緩衝response.text
這樣未解析前的響應內容(一般只在mime型別能夠匹配"text/","json","x-www-form-urlencoding"的情況下才進行緩衝),可以呼叫buffer()
方法,想取消預設的文字緩衝響應像text/plain
, text/html
這樣的,可以呼叫buffer(false)
方法。
// 強制緩衝 request .get('/userinfo') .buffer(true) .then(callback) // 取消緩衝 request .get('/userinfo') .buffer(false) .then(callback)
當緩衝response.buffered
標識有效了,那麼就可以在一個回撥函式里處理緩衝和未緩衝的響應.
25.跨域資源共享(CORS)
出於安全原因,瀏覽器將阻止跨源請求,除非伺服器使用CORS頭進行選擇。瀏覽器還將做出額外的選項請求,以檢查伺服器允許的HTTP頭和方法。更多資訊可參閱:.
withCredentials()
方法可以啟用傳送原始cookie
的能力,不過只有在Access-Control-Allow-Origin
不是一個萬用字元(*)
,並且Access-Control-Allow-Credentials
為’true’
的情況下才行。
request .get('') .withCredentials() .then(res => { assert.equal(200, res.status); assert.equal('tobi', res.text); })
26.錯誤處理
回撥函式總是會傳遞兩個引數:error
錯誤和response
響應。如果沒有發生錯誤,第一個引數將為null
。
request .post('/upload') .attach('image', 'path/to/tobi.png') .then(response => { });
你可以加入監聽錯誤的程式碼,錯誤產生之後會執行監聽程式碼。
request .post('/upload') .attach('image', 'path/to/tobi.png') .on('error', handle) .then(response => { });
注意:
superagent預設情況下,對響應4xx和5xx的認為不是錯誤,例如當響應返回一個500或者403的時候,這些狀態資訊可以透過response.error
,response.status
和其它的響應屬性來檢視。
不產生響應的網路故障、超時和其他錯誤將不包含response.error
,response.status
屬性。
如果希望處理404個或其他HTTP錯誤響應,可以查詢error.status
屬性。當發生HTTP錯誤(4xx或5xx響應)時,response.error
屬性是error
物件,這可以用來作以下檢查:
if (error && error.status === 404) { alert('oh no ' + response.body.message); }else if (error) { // all other error types we handle generically}
或者,可以使用ok(callback)
方法來判斷響應是否是錯誤。對ok()
的回撥得到響應,如果響應成功,則返回true。
request.get('/404') .ok(res => res.status { // reads 404 page as a successful response })
27.進度跟蹤
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 } */ }) .then()
event屬性包括:
direction
:upload
或download
percent
:0
到100
,檔案大小未知的話為無效total
:檔案總大小,可能為無效loaded
: 已經下載或上傳的位元組數
28.Promise和Generator支援
SuperAgent的請求是一個“thenable”物件,它與JavaScript承諾和非同步/等待語法相容。
如果你正在使用promises
,那麼就不要再呼叫end()
或pipe()
方法。任何使用then()
或者await
操作都會禁用所有其他使用請求的方式。
像CO或類似KOA這樣的Web框架,可以在superagent使用yield
:
const req = request .get('') .auth('tobi', 'learnboost');const res = yield req;
請注意,superagent期望全域性promises
物件存在。在Internet Explorer或Node.js 0.10中需要使用polyfill
元件。
29.瀏覽器和Node版本
SuperAgent有兩個實現:一個是用於web瀏覽器(使用XHR)的版本,另一個是用於Node.JS (使用核心的http模組)版本。
30.3XX處理
HTTP 3XX是重定向報文,superagent預設會自動跟蹤下去,我們也不能使用redirect(0)
的方法來禁止重定向,因此需要使用原生的http
來處理。
request.post({ url: '/login', }, function (err, res, body) { if (!err && (res.statusCode == 301 || res.statusCode == 302)) { // 登入成功後服務端返回重定位報文 cookie += ';' + res.headers['set-cookie'] res1.redirect('listall') } else if (res.statusCode == 200) { // 登入失敗服務端會返回200 // ... } else { // 其他錯誤資訊處理 console.log(err) } })
作者:李伯特
連結:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4830/viewspace-2814756/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- superagent 庫
- AJAX、$.ajax、axios、fetch、superagentiOS
- Minikube使用文件
- 使用apidoc文件神器,快速生成api文件API
- 使用Dbhavner 建立文件
- Bucardo使用文件-lottu
- 如何使用go文件Go
- JS HTTP 請求庫哪家強?Axios,Request,Superagent,Fetch 還是 SupertestJSHTTPiOS
- API文件使用方法API
- centos 7 yum 使用文件CentOS
- flask-maple使用文件Flask
- Express 文件(使用模板引擎)Express
- ApiBoot - ApiBoot Quartz 使用文件APIbootquartz
- fastjson使用說明文件ASTJSON
- 165 pbi-utils 使用文件
- 【Python】生成html文件-使用dominatePythonHTML
- 使用VuePress開心地寫文件Vue
- CodingDreamd的使用說明文件
- Express 文件(使用中介軟體)Express
- ApiBoot - ApiBoot Resource Load 使用文件APIboot
- 在RPA專案中有哪些文件,如何使用這些文件
- 使用 OpenCV 進行文件矯正OpenCV
- jQuery如何使用文件操作detach()方法jQuery
- 怎樣使用typora寫markdown文件
- Flv.js文件使用隨記JS
- Swagger 文件工具 設計、構建、文件化和使用您的 RESTful APISwaggerRESTAPI
- 使用開源文件工具docsify,用寫部落格的姿勢寫文件
- 使用halo快速搭建應用文件中心
- 使用 VS Code + Markdown 編寫 PDF 文件
- Go語言使用swagger生成介面文件GoSwagger
- 使用工具生成 Protocol 易讀文件Protocol
- 使用 YApi 管理 API 文件,測試, mockAPIMock
- 使用Swashbuckle構建RESTful風格文件REST
- knife4j api文件使用說明API
- bs4的使用 遍歷文件樹
- znai: 使用Markdown編寫Java文件系統AIJava
- .Net Api 之如何使用Elasticsearch儲存文件APIElasticsearch
- 如何使用 Sphinx 給 Python 程式碼寫文件Python