我曾寫過兩篇文章:jQuery進階:用最優雅的方式寫ajax請求, axios進階:用最優雅的方式寫ajax請求, 原理都是在將使用配置文件的方式,自動生成接口方法。 在多個項目中,我曾使用這種配置的方式批量生成ajax接口,可是每次都要造輪子是很繁瑣的,索性本身發佈一個npm包吧,因而xfire出來了。html
將配置數據從代碼中分離出來 -- 《編寫可維護的JavaScript》--Nicholas C. Zakas,我是看了這本書,才激發出用配置文件生成各類接口的想法。ios
xfire地址:點擊到達git
以爲不錯的話,能夠給xfire點個贊或者開個issue,或者提個建議。謝謝。github
很是簡單,高度可配置的fetch接口批量生成工具。
ajax
很是簡單: 提供配置文件,自動生成接口
提早驗證:支持請求體格式驗證
報錯詳細: 給出具體的報錯位置,字段信息
npm install -S xfire
yarn add xfire
複製代碼
首先須要一個配置文件npm
// api.config.js
export default {
prefix: 'http://localhost:80',
list: [
{
name: 'login',
desp: 'sercurity login',
path: '/agent/login',
method: 'post',
contentType: 'formData',
bodyStruct: {
username: 'string',
password: 'string',
namespace: 'string'
},
defaultBody: {
password: 'Aa123456'
},
status: {
401: 'username or password wrong'
}
},
{
name: 'heartBeat',
path: '/sdk/api/csta/agent/heartbeat/{{agentId}}',
},
{
name: 'setAgentState',
desp: 'set agent state',
path: '/sdk/api/csta/agent/state/{{namespace}}',
method: 'post',
bodyStruct: {
agentId: 'string?',
loginId: 'string',
func: 'string',
agentMode: 'string?',
device: 'string?',
password: 'string'
}
}
]
}
複製代碼
而後引入xfirejson
import xfire from 'xfire'
import apiConfig from './api.config.js'
const API = xfire.init(apiConfig)
複製代碼
POTS 發送formData類型的數據示例axios
API.login.fire({}, {
username: 'wangduanduan',
password: '123456',
namespace: 'dd.com'
})
.then((res) => {
console.log(res)
})
.catch((err) => {
console.log(err)
})
複製代碼
GET 數據示例segmentfault
API.heartBeat.fire({
agentId: '5001@dd.com'
})
.then((res) => {
console.log(res)
})
.catch((err) => {
console.log(err)
})
複製代碼
POST json類型數據示例windows
API.setAgentState.fire({
namespace: 'windows'
}, {
agentId: '5001@dd.com',
loginId: '5001@dd.com',
func: 'login',
agentMode: 'Ready',
device: '8001@dd.com',
password: '123456'
})
.then((res) => {
console.log(res)
})
.catch((err) => {
console.log(err)
})
複製代碼
const API = xfire.init(config)
複製代碼
config 字段說明
注意:若是config沒法經過下面的格式驗證,則會直接報錯
字段名 | 類型 | 是否必須 | 默認值 | 說明 |
---|---|---|---|---|
config.prefix | string | 是 | 無 | 接口url公用的前綴 |
config.list | array | 是 | 無 | 接口數組 |
config list字段說明
字段名 | 類型 | 是否必須 | 默認值 | 說明 |
---|---|---|---|---|
name |
string | 是 |
無 | 接口名 |
desp | string | 否 | 無 | 接口描述 |
path |
string | 是 |
無 | 接口路徑 |
method | enum string | 否 | get | 請求方式: get, post, put, delete |
contentType | enum string | 否 | json | 請求體類型: json, formData。json會被渲染: application/json; charset=UTF-8, formData會被渲染成: application/x-www-form-urlencoded; charset=UTF-8 |
bodyStruct | object | 否 | 無 | 請求體格式驗證結構, 若是bodyStruct存在,則使用bodyStruct驗證body: 具體格式參考superstruct |
defaultBody | object | 否 | 無 | 默認請求體。bodyStruct存在的狀況下才有效 |
status | object | 否 | 無 | 響應狀態碼及其含義 |
當某個list對象的 name 不存在時,config驗證時的報錯:
Uncaught StructError: Expected a value of type `string` for `name` but received `undefined`.
複製代碼
當發送請求時,請求體不符合bodyStruct時, 報錯以下
...
name: 'login',
desp: 'sercurity login',
path: '/agent/login',
method: 'post',
contentType: 'formData',
bodyStruct: {
username: 'string',
password: 'string',
namespace: 'string'
},
...
API.login.fire({}, {
// username: '5001',
password: 'Aa123456',
namespace: 'zhen04.cc'
})
Uncaught StructError: Expected a value of type `string` for `username` but received `undefined`.
複製代碼
xfire.init()方法會返回xfire實例對象,該對象上有一個特殊方法$setHeaders
, 還有其餘的由配置文件產生的方法。
const API = xfire.init(apiConfig)
複製代碼
$setHeaders()用來設置除了contentType
之外的請求頭, 一旦設置請求頭部信息,全部的實例接口在發送請求時,都會帶有該頭部信息。
API.$setHeaders({sessionId: 'jfsldkf-sdflskdjf-sflskfjlsf'})
複製代碼
pathParm對象上的數據最終會被渲染到請求路徑上
, body是請求體。
...
{
name: 'heartBeat',
desp: 'agent heart beat',
path: '/sdk/api/csta/agent/heartbeat/{{agentId}}',
method: 'post'
},
...
複製代碼
相似上面的對象,會產生一個以heartBeat
爲名稱的方法,全部請求方法都是fire()方法。
API.xxx.fire(pathParm, body)
// 不須要請求體時, body能夠不傳
API.xxx.fire(pathParm)
// 不須要參數渲染到路徑時,pathParm必須傳空對象:{}
API.xxx.fire({}, body)
複製代碼
例子:
API.heartBeat({
agentId: '5001@ee.com'
})
.then((res) => {
console.log(res)
})
.catch((err) => {
console.log(err)
})
複製代碼
關於path
和 fire的 pathParm
參數:
// path 以下
path: '/store/order/{{type}}/{{age}}'
// 則pathParm應該是
{
type: 'dog',
age: 14
}
複製代碼
注意
: pathParm不支持複雜的數據類型。
// 原始數據類型 string, number, boolean 都是能夠的
{
key1: 'string',
key2: number,
key3: boolean
}
// 複雜的數據類型,如數組和嵌套對象, 函數, 將致使渲染失敗
// bad
{
key1: [1, 3, 3],
key2: {
key3: 'string'
},
key4: function(){}
}
複製代碼
xfire底層使用了瀏覽器原生的Promise
, fetch
, Object.keys()
, Object.assign()
因此對瀏覽器是有要求的。xfire自己不帶有任何polyfill。
目前IE11以及如下是不支持Promise和fetch的。
在此給出兩個方案:
經過引入babel-polyfill, 讓瀏覽器支持xfire所須要的原生方法。
只須要爲您的網站,爲每一個瀏覽器量身定製的polyfills。 複製代碼釋放魔法:
<script src="https://cdn.polyfill.io/v2/polyfill.min.js"></script>
複製代碼
Polyfill.io讀取每一個請求的User-Agent頭並返回適合請求瀏覽器的polyfill。 根據您在應用中使用的功能量身定製響應,並查看咱們的實例以快速入門。
與其使用各類ajax第三方庫,不如使用原始fetch。ajax是過去,fetch是如今和未來。
總結一下,Fetch 優勢主要有:
語法簡潔,更加語義化 基於標準 Promise 實現,支持 async/await 同構方便,使用 isomorphic-fetch --傳統 Ajax 已死,Fetch 永生 將來更容易擴展 -- by me
我使用ajax經歷過三個階段:
ajax
fetch
Fetch API 提供了一個 JavaScript接口,用於訪問和操縱HTTP管道的部分,例如請求和響應。它還提供了一個全局 fetch()方法,該方法提供了一種簡單,合乎邏輯的方式來跨網絡異步獲取資源。-- MDN
這種功能之前是使用 XMLHttpRequest實現的。Fetch提供了一個更好的替代方法,能夠很容易地被其餘技術使用,例如 Service Workers。Fetch還提供了單個邏輯位置來定義其餘HTTP相關概念,例如 CORS和HTTP的擴展。-- MDN
從caniuse的數據來看,fetch方法除IE11不支持之外,大部分經常使用瀏覽器都支持了。
fetch接口示例:
fetch('/users.json')
.then(function(response) {
return response.json()
}).then(function(json) {
console.log('parsed json', json)
}).catch(function(ex) {
console.log('parsing failed', ex)
})
fetch('/users.html')
.then(function(response) {
return response.text()
}).then(function(body) {
document.body.innerHTML = body
})
複製代碼
微軟公司正式宣佈:從當地時間2016年1月12日,中止對IE 8/9/10三個版本的技術支持,相應的用戶將不會再收到任何來自微軟官方的IE安全更新。-- Support for older versions of Internet Explorer ended