Fly
轉載至 這位大佬
Fly.js 是一個基于 promise 的,輕量且強大的Javascript http 網絡庫,它有如下特點:
提供統一的 Promise API。
瀏覽器環境下,輕量且非常輕量 。
支持多種JavaScript 運行環境
支持請求/響應攔截器。
自動轉換 JSON 數據。
支持切換底層 Http Engine,可輕松適配各種運行環境。
瀏覽器端支持全局Ajax攔截 。
H5頁面內嵌到原生 APP 中時,支持將 http 請求轉發到 Native。支持直接請求圖片。
定位與目標
Fly 的定位是成為 Javascript http請求的終極解決方案。也就是說,在任何能夠執行 Javascript 的環境,只要具有訪問網絡的能力,Fly都能運行在其上,提供統一的API。
官網
詳細的文檔請移步:Flyio官網文檔 。 官網http請求使用的正是fly,為了方便大家驗證fly功能特性,官網對fly進行了全局引入,您可以在官網頁面打開控制臺直接驗證。
安裝
使用NPM
npm install flyio
使用CDN(瀏覽器中)
UMD(瀏覽器中)
https://unpkg.com/flyio/dist/umd/fly.umd.min.js
引入flyio
不同JavaScript運行時的入口文件不同 ,請查看文檔后面相應平臺的引入方式,但在瀏覽器、Node、React Native中引入的方式是一樣的,下面是不同平臺下的引入的方式:
瀏覽器、Node、React Native中引入
//引入fly實例var fly=require(“flyio”)
上面方式引入的是Fly的默認實例(瀏覽器、Node、React Native中相同),你也可以自己創建Fly實例:
// 瀏覽器和React Nativevar Fly=require(“flyio/dist/npm/fly”)
// Node 入口// var Fly=require(“flyio/src/node”)var fly=new Fly;
在微信小程序中引入
var Fly=require(“flyio/dist/npm/wx”)
var fly=new Fly
如果您的微信小程序項目沒有使用npm來管理依賴,您可以直接下載源碼到您的小程序工程,下載鏈接wx.js 或 wx.umd.min.js .下載任意一個,保存到本地工程目錄,假設在“lib”目錄,接下來引入:
var Fly=require("…/lib/wx") //wx.js為您下載的源碼文件var fly=new Fly; //創建fly實例
在支付寶小程序中引入
var Fly=require(“flyio/dist/npm/ap”)
var fly=new Fly
如果您的支付寶小程序項目沒有使用npm來管理依賴,您可以直接下載源碼到您的小程序工程,下載鏈接ap.js 或 ap.umd.min.js .下載任意一個,保存到本地工程目錄,假設在“lib”目錄,接下來引入:
var Fly=require("…/lib/ap") //ap.js為您下載的源碼文件var fly=new Fly; //創建fly實例
快應用中引入
快應用 中Fly依賴 fetch模塊,需要先在 manifest.json中添加引用:
“features”: [
…
{“name”: “system.fetch”}
]
然后創建fly實例
//依賴快應用中的fetch模塊,需要在
var fetch = require("@system.fetch")
var Fly=require(“flyio/dist/npm/hap”)
var fly=new Fly(fetch)
Weex中引入
var Fly=require(“flyio/dist/npm/weex”)
var fly=new Fly
引入之后,您就可以對fly實例進行全局配置、添加攔截器、發起網絡請求了。
例子
下面示例如無特殊說明,則在所有支持的平臺下都能執行。
發起GET請求
//通過用戶id獲取信息,參數直接寫在url中fly.get(’/user?id=133’)
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
//query參數通過對象傳遞fly.get(’/user’, {
id: 133
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
發起POST請求
fly.post(’/user’, {
name: ‘Doris’,
age: 24
phone:“18513222525”
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
Post請求添加Url參數
fly.get("…/package.json", “xxx=5”, {
params: {
c: 1
}
}
)
最終的URL是“package.json?c=1&xxx=5”。
發起多個并發請求
function getUserRecords() {
return fly.get(’/user/133/records’);
}
function getUserProjects() {
return fly.get(’/user/133/projects’);
}
fly.all([getUserRecords(), getUserProjects()])
.then(fly.spread(function (records, projects) {
//兩個請求都完成
}))
.catch(function(error){
console.log(error)
})
直接通過 request 接口發起請求
//直接調用request函數發起post請求fly.request("/test",{hh:5},{
method:“post”,
timeout:5000 //超時設置為5s
})
.then(d=>{ console.log(“request result:”,d)})
.catch((e) => console.log(“error”, e))
發送URLSearchParams
const params = new URLSearchParams();
params.append(‘a’, 1);
fly.post("",params)
.then(d=>{ console.log(“request result:”,d)})
注:Node環境不存在URLSearchParams。各個瀏覽器對URLSearchParams的支持程度也不同,使用時務必注意
發送 FormData
var formData = new FormData();
var log=console.log
formData.append(‘username’, ‘Chris’);
fly.post("…/package.json",formData).then(log).catch(log)
注:Fly目前只在支持 FormData 的瀏覽器環境中支持 FormData,Node環境下對 FormData 的支持方式稍有不同,詳情戳這里 Node 下增強的API
請求二進制數據
fly.get("/Fly/v.png",null,{
responseType:“arraybuffer”
}).then(d=>{
//d.data 為ArrayBuffer實例
})
注:在瀏覽器中時 responseType 值可為 “arraybuffer” 或"blob"之一。在node下只需設為 "stream"即可。
攔截器
Fly支持請求/響應攔截器,可以通過它在請求發起之前和收到響應數據之后做一些預處理。
//添加請求攔截器fly.interceptors.request.use((request)=>{
//給所有請求添加自定義header
request.headers[“X-Tag”]=“flyio”;
//打印出請求體
console.log(request.body)
//終止請求
//var err=new Error(“xxx”)
//err.request=request
//return Promise.reject(new Error(""))
//可以顯式返回request, 也可以不返回,沒有返回值時攔截器中默認返回request
return request;
})
//添加響應攔截器,響應攔截器會在then/catch處理之前執行fly.interceptors.response.use(
(response) => {
//只將請求結果的data字段返回
return response.data
},
(err) => {
//發生網絡錯誤后會走到這里
//return Promise.resolve(“ssss”)
}
)
請求攔截器中的request對象結構如下:
{
baseURL, //請求的基地址
body, //請求的參數
headers, //自定義的請求頭
method, // 請求方法
timeout, //本次請求的超時時間
url, // 本次請求的地址
params, //url get參數(post請求或默認的get參數)
withCredentials, //跨域請求是否發送第三方cookie
… //options中自定義的屬性
}
響應攔截器中的response對象結構如下:
{
data, //服務器返回的數據
engine, //請求使用的http engine(見下面文檔),瀏覽器中為本次請求的XMLHttpRequest對象
headers, //響應頭信息
request //本次響應對應的請求信息,即上面的request結構
}
移除攔截器
如果你想移除攔截器,只需要將攔截器設為null即可:
fly.interceptors.request.use(null)
fly.interceptors.response.use(null,null)
在攔截器中執行異步任務
現在,您可以在攔截器中執行異步任務了!
下面我們看一個例子:由于安全原因,我們需要所有的請求都需要在header中設置一個csrfToken,如果csrfToken不存在時,我們需要先請求一個csrfToken,然后再發起網絡請求,由于請求csrfToken是異步的,所以我們需要在攔截器中執行異步請求,代碼如下:
var csrfToken="";
var tokenFly=new Fly();
var fly=new Fly();
fly.interceptors.request.use(function (request) {
log(發起請求:path:${request.url},baseURL:${request.baseURL})
if (!csrfToken) {
log(“沒有token,先請求token…”);
//鎖定當天實例,后續請求會在攔截器外排隊
fly.lock();
return newFly.get("/token").then((d) => {
request.headers[“csrfToken”] = csrfToken = d.data.data.token;
log("token請求成功,值為: " + d.data.data.token);
log(繼續完成請求:path:${request.url},baseURL:${request.baseURL})
return request; //只有最終返回request對象時,原來的請求才會繼續
}).finally(()=>{
//fly.clear(); //clear the request queue
fly.unlock();//解鎖后,會繼續發起請求隊列中的任務
})
} else {
request.headers[“csrfToken”] = csrfToken;
}
})
注意:
當前Fly實例會在調用fly.lock時會被鎖定,fly實例鎖定后,接下來的請求在進入請求攔截器前會進入一個隊列排隊,當解鎖后(通過調用fly.unlock),才會進入攔截器,這提供一種同步多個任務的方式。如果你想取消隊列里的所有請求,可以調用fly.clear() 。
只有當最終返回request對象時(攔截器傳遞給你的回調參數),請求才會繼續(如代碼中注釋), 否則將會把返回的值作為本次請求。
有關攔截器的詳細信息和示例,請參閱flyio interceptor。
錯誤處理
請求失敗之后,catch 捕獲到的 err 是一個對象,它的字段如下:
{
message:“Not Find 404”, //錯誤消息
status:404, //如果服務器可通,則為http請求狀態碼。網絡異常時為0,網絡超時為1
request:{…}, //對應的請求信息
response:{}, //響應信息
engine:{}//請求使用的http engine(見下面文檔),瀏覽器中為本次請求的XMLHttpRequest對象
}
錯誤碼
錯誤碼
含義
0
網絡錯誤
1
請求超時
2
文件下載成功,但保存失敗,此錯誤只出現node環境下
=200
http請求狀態碼
示例
fly.get(’/user/12345’)
.catch(function (error) {
console.log(‘Error’, error.message);
console.log(‘Error engine:’, error.engine)
// The request was made but no response was received
// error.request holds the request info.
console.log(‘Error request info:’,error.request);
if (error.response) {
// The request was made and the server responded with a status code
// that falls out of the range of 2xx and 304
console.log(error.response.data);
console.log(error.response.status);
console.log(error.response.statusText);
console.log(error.response.headers);
}
});
請求配置選項
可配置選項:
{
headers:{}, //http請求頭,
baseURL:"", //請求基地址
timeout:0,//超時時間,為0時則無超時限制
//是否自動將Content-Type為“application/json”的響應數據轉化為JSON對象,默認為true
parseJson:true,
params:{}, //默認公共的url get參數
withCredentials:false //跨域時是否發送cookie
}
配置支持實例級配置和單次請求配置
實例級配置
實例級配置可用于當前Fly實例發起的所有請求
//定義公共headersfly.config.headers={xx:5,bb:6,dd:7}
//設置超時fly.config.timeout=10000;
//設置請求基地址fly.config.baseURL=“https://wendux.github.io/”//設置公共的Get參數fly.config.params={“token”:“testtoken”};
單次請求配置
需要對單次請求配置時,配置只對當次請求有效。
fly.request("/test",{hh:5},{
method:“post”,
timeout:5000 //超時設置為5s
})
注:若單次配置和實例配置沖突,則會優先使用單次請求配置
詳細的配置請參考 Fly請求配置 。
API
fly.get(url, data, options)
發起 get 請求,url請求地址,data為請求數據,在瀏覽器環境下類型可以是:
String|Json|Object|Array|Blob|ArrayBuffer|FormData
options為請求配置項。
fly.post(url, data, options)
發起post請求,參數含義同fly.get。
fly.request(url, data, options)
發起請求,參數含義同上,在使用此API時需要指定options 的method:
//GET請求fly.request("/user/8" null, {method:“get”})
//DELETE 請求fly.request("/user/8/delete", null, {method:“delete”})
//PUT請求fly.request("/user/register", {name:“doris”}, {method:“PUT”})
…
request 適合在 RESTful API 的場景下使用,為了方便使用,fly提供了響應的別名方法
別名方法
fly.put(url, data, options)
fly.delete(url,data,options)
fly.patch(url,data,options)
fly.all([])
fly.spread([])
發起多個并發請求,參數是一個promise 數組;當所有請求都成功后才會調用then,只要有一個失敗,就會調 catch。
使用application/x-www-form-urlencoded 編碼
Fly默認會將JavaScript objects 序列化為 JSON 發送(RequestBody),如果想以 application/x-www-form-urlencoded 編碼格式發送,你可以使用如下方式:
通過設置請求頭
將請求頭content-type設置為"application/x-www-form-urlencoded"后fly會自動對請求數據進行編碼,如:
fly.post("…/package.json",{aa:8,bb:9,tt:{xx:5}},{headers:{
“content-type”:“application/x-www-form-urlencoded”
}})
.then(console.log)
這種方法是通用的,意味著在任何JavaScript運行環境下都能正常工作,還有一些其它特定平臺的方法:
其它方法
瀏覽器中
在瀏覽器中, 你可以使用 URLSearchParams ,如下:
var params = new URLSearchParams();
params.append(‘param1’, ‘value1’);
params.append(‘param2’, ‘value2’);
fly.post(’/foo’, params);
注意,現在不是所有瀏覽器都支持 URLSearchParams (參考 caniuse.com), 但是有一個 polyfill 可用 (確保polyfill為全局變量).
另一種方法,你可以使用 qs 庫:
var qs = require(‘qs’);
fly.post(’/foo’, qs.stringify({ ‘bar’: 123 }));
Node.js
在node中,你可以使用 querystring 模塊,如:
var querystring = require(‘querystring’);
fly.post(‘http://something.com/’, querystring.stringify({ foo: ‘bar’ }));
你仍然可以使用 qs 庫.
Promises
Fly 依賴 ES6 Promise 支持情況. 如果你的環境不支持 ES6 Promises, 你需要 polyfill.
TypeScript
Fly 提供了 TypeScript 描述文件.你可以在TypeScript中方便使用:
import fly from ‘flyio’;
fly.get(’/user?ID=12345’);
創建Fly實例
為方便使用,在引入flyio庫之后,會創建一個默認實例,一般情況下大多數請求都是通過默認實例發出的,但在一些場景中需要多個實例(可能使用不同的配置請求),這時你可以手動new一個:
//npm、node環境下var Fly=require(“flyio/dist/npm/fly”) //注意!此時引入的是 "flyio/dist/npm/fly"var nFly=new Fly();
//CDN引入時直接newvar nFly=new Fly();
Http engine
Fly 引入了Http engine 的概念,所謂 Http engine,就是真正發起http請求的引擎,這在瀏覽器中一般都是XMLHttpRequest,而在 node 環境中,可以用任何能發起網絡請求的庫/模塊實現,Fly 可以自由更換底層 http engine ,Fly 正是通過更換 engine 而實現同時支持 node 和 browser 。值得注意的是,http engine 不局限于node 和 browser 環境中,也可以是 android、ios、electron,正是由于這些,Fly 才有了一個非常強大的功能——請求重定向?;谡埱笾囟ㄏ?#xff0c;我們可以實現一些非常有用的功能,比如將內嵌到 APP 的所有 http 請求重定向到 Native ,然后在端上( android、ios )統一發起網絡請求、進行 cookie 管理、證書校驗。詳情請戳 Fly Http Engine
全局Ajax攔截
在瀏覽器中,可以通過用 Fly engine 替換 XMLHttpRequest 的方式攔截全局的的 Ajax 請求,無論上層使用的是何種網絡庫。詳細的內容請參考 Fly攔截全局Ajax
Node
無論是在瀏覽器環境,還是在 Node 環境,Fly在上層提供了統一的 Promise API。這意味著無論您是 web 開發還是 node 開發,您都可以以相同的調用方式來發起http請求。不過,由于node和瀏覽器環境本身的差異,在Node環境下,Fly除了支持基本的API之外,還提供了一些增強的API,這些 API 主要涉及文件下載、多文件上傳、http代理等眾多強大的功能,詳情請參考 Node下增強的API
體積
在瀏覽器環境下,一個庫的大小是非常重要的。這方面 Fly 做的很好,它在保持強大的功能的同時,將自己的身材控制到了最好。min 只有 4.6K 左右,GZIP 壓縮后不到 2K,體積是 axios 的四分之一。
工程目錄結構
工程目錄結構及文件說明請參照 fly源碼目錄說明 。
總結
- 上一篇: 湖南大学.大学物理实验3:用分光计测量三
- 下一篇: vrrp路由器三种状态_VRRP路由器切