六九、ajax,fetch,axios,wx.request封裝
前端開發不可避免的介面請求,而在使用原生ajax,或者其他包的時候要麼功能不全,要麼包太大,所有統一封裝一套供日常開發使用。
axios封裝
- 推薦vue框架中使用
// index.js
import axios from 'axios'
import { Toast } from 'vant'
// 建立一個錯誤
function errorCreate (msg) {
const error = new Error(msg)
errorLog(error)
throw error
}
// 記錄和顯示錯誤
function errorLog (error) {
// 列印到控制檯
if (process.env.NODE_ENV === 'development') {
console.log('>>>>>> Error >>>>>>')
console.log(error)
}
// 顯示提示
Toast({
message: error.message,
type: 'error',
duration: 5 * 1000
})
}
// 建立一個 axios 例項
// const host = window.location.host
const service = axios.create({
baseURL: process.env.NODE_ENV === 'development' ? 'http://192.168.1.200:81' : 'http://video.uniqorn.com.cn',
timeout: 5000 // 請求超時時間
})
// 請求攔截器
service.interceptors.request.use(
config => {
// 在請求傳送之前做一些處理
// const token = util.cookies.get('token')
// 讓每個請求攜帶token-- ['X-Token']為自定義key 請根據實際情況自行修改
// config.headers['X-Token'] = token
return config
},
error => {
// 傳送失敗
console.log(error)
Promise.reject(error)
}
)
// 響應攔截器
service.interceptors.response.use(
response => {
// dataAxios 是 axios 返回資料中的 data
const dataAxios = response.data
// 這個狀態碼是和後端約定的
const { code } = dataAxios
// 根據 code 進行判斷
if (code === undefined) {
// 如果沒有 code 代表這不是專案後端開發的介面 比如可能是 D2Admin 請求最新版本
return dataAxios
} else {
// 有 code 代表這是一個後端介面 可以進行進一步的判斷
switch (code) {
case 200:
// [ 示例 ] code === 0 代表沒有錯誤
return dataAxios.data
case -403:
Toast('未登入,請先登入!')
// [ 示例 ] 其它和後臺約定的 code
// router.push({
// name: 'login'
// })
break
default:
// 不是正確的 code
errorCreate(`${dataAxios.msg}: ${response.config.url}`)
break
}
}
},
error => {
if (error && error.response) {
switch (error.response.status) {
case 400:
error.message = '請求錯誤'
break
case 401:
error.message = '未授權,請登入'
break
case 403:
error.message = '拒絕訪問'
break
case 404:
error.message = `請求地址出錯: ${error.response.config.url}`
break
case 408:
error.message = '請求超時'
break
case 500:
error.message = '伺服器內部錯誤'
break
case 501:
error.message = '服務未實現'
break
case 502:
error.message = '閘道器錯誤'
break
case 503:
error.message = '服務不可用'
break
case 504:
error.message = '閘道器超時'
break
case 505:
error.message = 'HTTP版本不受支援'
break
default:
break
}
}
errorLog(error)
return Promise.reject(error)
}
)
class Http {
$http (params) {
// const token = util.cookies.get('token')
// if (token) params.data.token = token
return new Promise((resolve, reject) => {
!params.isNoLoading && Toast.loading({
duration: 0, // 持續展示 toast
forbidClick: true,
message: '...'
})
service({
method: params.method || 'get',
url: params.url,
header: {
'content-type': 'application/x-www-form-urlencoded'
},
params: params.data || {}
}).then((res) => {
resolve(res)
}).catch(e => {
reject(e)
}).finally(() => {
Toast.clear() //關閉loading
})
})
}
}
export default Http
// api.js
import Fetch from './index'
class Api extends Fetch {
// eslint-disable-next-line no-useless-constructor
constructor () {
super()
}
/**
*獲取視訊詳情
* @returns {*}
* @private
*/
_getVideoInfo (data) {
return this._init('/api/video/info', data, false)
}
_init (url, data, method, isNoLoading) {
const params = {
url,
data,
method,
isNoLoading, //是否顯示loading
}
return this.$http(params)
}
}
export default Api
//main.js
// 定義全域性api 也可使用install 定義use
import Api from './api/api'
Vue.prototype.Api = new Api()
// 頁面中使用
async _handleVideoInfo() {
let res = await this.Api._getVideoInfo({videoId:1})
console.log(res)
}
ajax封裝
- 適用於所有框架或者原生開發
const config={
IS_DEV_ENV : process.env.NODE_ENV !== 'production',
XHR_RES_CODE : {
SUCCESS: 0,
REDIRECT: 110
}
}
const ajax = {
_request: (options) => {
return new Promise((onResolve, onReject) => {
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = () => {
if (xhr.readyState.toString() === '4') {
let response;
try {
response = JSON.parse(xhr.responseText);
}
catch (err) {
response = xhr.responseText;
}
if (xhr.status >= 200 && xhr.status < 400) {
const isRedirect = typeof response.err !== 'undefined' && response.err === config.XHR_RES_CODE.REDIRECT;
const isSuccess = typeof response.err !== 'undefined' && response.err === config.XHR_RES_CODE.SUCCESS;
if (isRedirect) {
onResolve(response);
window.location.href = config.IS_DEV_ENV ? '../login/' : '/login';
}
else if (isSuccess) {
onResolve(response);
}
else {
onReject(response);
}
}
else {
onReject(response);
}
}
};
if (options.type.toLowerCase() === 'get' && options.params != null) {
const qs = Object.keys(options.params).map((key) => {
return `${key}=${options.params[key]}`;
}).join('&').trim();
options.url = qs === '' ? `${options.url}` : `${options.url}?${qs}`;
options.params = null;
}
xhr.open(options.type, options.url, true);
if (options.header) {
xhr.setRequestHeader('Content-Type', options.header);
}
xhr.timeout = 1000 * 30;
xhr.send(options.params);
});
},
get: (options) => {
options.type = 'GET';
return ajax._request(options);
},
post: (options) => {
options.type = 'POST';
options.header = 'application/json';
options.params = JSON.stringify(options.params);
return ajax._request(options);
}
};
export default ajax;
fetch封裝
- 推薦react框架中使用
const CREDS = 'include'
function checkStatus (response) {
if (response.status >= 200 && response.status < 300) { return response }
const error = new Error(response.statusText)
error.response = response
throw error
}
const asyncFetch = async function (obj) {
const url = obj.url || obj
const method = obj.method || 'GET'
const credentials = obj.credentials || CREDS
const body = obj.obj || null
let confFetch = { method, credentials }
if (method === 'POST') { confFetch = { method, credentials, body: JSON.stringify(body) } }
return new Promise(function (resolve, reject) {
fetch(url, confFetch)
.then(checkStatus)
.then(res => res.json())
.then(res => { resolve(res) })
.catch(err => { reject(err) })
})
}
export default asyncFetch
wx.request封裝
- 小程式中使用
//fetch.js
export default class Fetch {
constructor() {
this.host = https; /* 全域性域名*/
}
$http(params) {
let sessionId = wx.getStorageSync('sessionId')
!params.isNoLoading && wx.showLoading({
title: params.loadingText || '資料載入中...',
mask: 'true'
})
return new Promise((resolve, reject) => {
wx.request({
method: params.method || 'GET',
url: `${this.host}${params.url}?sessionId=${sessionId}`,
header: {
'content-type': params.contentType || 'application/json' || 'application/x-www-form-urlencoded'
},
data: params.data || {},
success: (res) => {
if (res.data.status === 200) {
resolve(res.data.data)
} else {
reject(res.data.msg)
wx.showToast({
title: res.data.msg,
icon: 'none',
duration: 2000
})
}
},
fail() {
reject
},
complete() {
wx.hideLoading()
}
})
})
}
}
api.js
import Fetch from './fetch'
class Api extends Fetch {
constructor() {
super()
}
/**
* 取消關注
* @param data -delete
* @returns {Promise<any>}
* @private
*/
_cancelFollow(data) {
const params = {
url: '/app/follow/deleteByBeOpenId',
data,
method: 'DELETE',
isNoLoading: true
}
return this.$http(params)
}
}
export default {
API: new Api()
}
相關文章
- ajax,axios,fetchiOS
- AJAX、$.ajax、axios、fetch、superagentiOS
- 封裝ajax、axios請求封裝iOS
- axios,Ajax,jQuery ajax,axios和fetch的區別iOSjQuery
- 從ajax到fetch、axiosiOS
- ajax、axios、fetch、jsonp、corsiOSJSONCORS
- 對ajax、axios、fetch的認識iOS
- ajax和axios、fetch的區別iOS
- promise封裝wx.request()Promise封裝
- ajax和fetch、axios的區別以及axios原理iOS
- 使用promise封裝wx.request()Promise封裝
- 【axios】XHR的ajax封裝+axios攔截器呼叫+請求取消iOS封裝
- ajax,fetch,axios的區別及運用iOS
- 基於小程式請求介面 wx.request 封裝的類 axios 請求封裝iOS
- axios封裝iOS封裝
- 封裝axios封裝iOS
- 前端知識總結之Ajax,axios,fetch篇前端iOS
- Ajax、fetch、axios的區別與優缺點iOS
- Ajax,jQuery ajax,axios和fetch介紹、區別以及優缺點jQueryiOS
- 微信小程式 wx.request 的封裝微信小程式封裝
- ajax 封裝封裝
- AJAX API三駕馬車: Axios vs . jQuery和FetchAPIiOSjQuery
- axios封裝apiiOS封裝API
- 小程式wx.request()方法簡單封裝封裝
- Fetch API 簡單封裝API封裝
- 封裝axios請求封裝iOS
- 小程式 二次封裝wx.request方法封裝
- 微信小程式wx.request的簡單封裝微信小程式封裝
- 資料互動——Promise、Ajax、axios和fetch的優缺點PromiseiOS
- ajax原生js封裝JS封裝
- 原生js封裝AjaxJS封裝
- jquery ajax 的封裝jQuery封裝
- 基於原生fetch封裝一個帶有攔截器功能的fetch,類似axios的攔截器封裝iOS
- Fetch方法封裝、業務實踐封裝
- Vue Axios 的封裝使用VueiOS封裝
- axios二次封裝iOS封裝
- 非同步請求xhr、ajax、axios與fetch的區別比較非同步iOS
- ajax、axios、fetch之間的詳細區別以及優缺點iOS