jQuery的ajax與axios和fetch優缺點
1.jQuery ajax
$.ajax({
type: 'POST',
url: url,
data: data,
dataType: dataType,
success: function () {},
error: function () {}
});
優缺點:
-
本身是針對MVC的編程,不符合現在前端MVVM的浪潮
-
基于原生的XHR開發,XHR本身的架構不清晰,已經有了fetch的替代方案
-
JQuery整個專案太大,單純使用ajax卻要引入整個JQuery非常的不合理(采取個性化打包的方案又不能享受CDN服務)
2.axios
axios({
method: 'post',
url: '/user/12345',
data: {
firstName: 'Fred',
lastName: 'Flintstone'
}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
優缺點:
- 從 node.js 創建 http 請求
- 支持 Promise API
- 客戶端支持防止CSRF(跨站請求偽造)
- 提供了一些并發請求的介面(重要,方便了很多的操作)
3.fetch
try {
let response = await fetch(url);
let data = response.json();
console.log(data);
} catch(e) {
console.log("Oops, error", e);
}
優缺點:
- 符合關注分離,沒有將輸入、輸出和用事件來跟蹤的狀態混雜在一個物件里
- 更好更方便的寫法
- 更加底層,提供的API豐富(request, response)
- 脫離了XHR,是ES規范里新的實作方式
- 1)fetcht只對網路請求報錯,對400,500都當做成功的請求,需要封裝去處理
- 2)fetch默認不會帶cookie,需要添加配置項
- 3)fetch不支持abort,不支持超時控制,使用setTimeout及Promise.reject的實作的超時控制并不能阻止請求程序繼續在后臺運行,造成了量的浪費
- 4)fetch沒有辦法原生監測請求的進度,而XHR可以
重點 axios的二次封裝
import axios from 'axios'
import qs from 'qs'
switch (process.env.NODE_ENV) {
case "production":
axios.defaults.baseURL = "http.....";
case "test":
axios.defaults.baseURL = "http.....";
default:
axios.defaults.baseURL = 'http'
}
axios.defaults.timeout = 10000;
axios.defaults.withCredentials = true;
axios.defaults.headers['Content-Type'] = 'application/x-www-form-urlencoded';
axios.defaults.transfromRequest = data => qs.stringify(data);
axios.interceptors.request.use(config => {
let token = localStorage.getItem('token');
token && (config.headers.Authorization = token);
return config;
}, error => {
//如果攔截失敗回傳失敗資訊
return Promise.reject(error)
})
/*
*回應攔截器
* 服務器回傳資訊 ->[攔截的統一處理] -> 客戶端js獲取到資訊
*/
// axios.defaults.validateStatus = status => {
// //自定義回應成功的http狀態碼,默認只有2或者3開頭的回應碼
// return /^(2|3)\d{2}$/.test(status)
// }
axios.interceptors.response.use(response => {
return response.data; //只回傳回應的主體內容
}, error => {
if (error.response) {
//如果服務器有回傳資訊
switch (error.response.status) {
case 401: //當前請求需要用戶驗證(一般是未登錄)
break;
case 403: //服務器已經理解請求,但是拒絕執行他(一般是TOKEN過期)
localStorage.removeItem('token');
//跳轉的登錄頁面
break;
case 404: //請求失敗,請求所希望的到的資源未被在服務器上發現
break;
}
return Promise.reject(error, response)
} else { // 如果服務器沒有回傳資訊
//斷網處理
if (!window.navigator.onLine) {
//網路斷開了,可以讓其跳轉到斷網頁面
return
}
return Promise.reject(error)
}
})
export default axios
fetch的封裝
import qs from 'qs'
import { delete } from 'vue/types/umd';
/*
* 根據環境變數進行介面區分
*/
let baseURL = '';
let baseURLArr = [{
type: 'development',
url: 'http://127.0.0.1:8080'
}, {
type: 'test',
url: 'http://XXXX'
}, {
type: 'production',
url: 'http://XXXX'
}];
baseURLArr.forEach(item => {
if (process.env.NODE_ENV === item.type) {
baseURL = item.url;
}
})
export default function request(url, options = {}) {
url = baseURL + url;
/*
* GET 系列請求的處理
* 正常請求 request(url,{
* params:{
* method:'get'
* }
* })
*/
!options.method ? options.method = 'GET' : null;
if (options.hasOwnProperty('params')) {
if (/^(GET|DELETE|HEAD|OPTIONS)$/i.test(options.method)) {
const ask = url.includes('?') ? '&' : '?';
url += `${ask}${qs.stringify(params)}`;
}
delete options.params; //應為fetch中沒有params,所以用完后贏移除
}
/*
* 合并配置項
*/
options = Object.assign({
//允許跨域攜帶資源憑證 same-origin 同源可以 omit都拒絕
credentials: 'include', //不管同源不同元都可以攜帶資源憑證
//設定請求頭
headers: {}
}, options);
options.headers.Accept = 'application/json';
/*
*token的校驗
*/
const token = localStorage.getItem('token');
token && (options.headers.Authorization = token);
/*
* post 請求的處理
*/
if (/^(POST|PUT)$/i.test(options.method)) {
!options.type ? options.type = 'urlencoded' : null;
if (options.type === 'urlencoded') {
options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
options.body = qs.stringify(options.body);
}
if (options.type === 'json') {
options.headers['Content-Type'] = 'application/json';
options.body = JSON.stringify(options.body);
}
}
return fetch(url, options).then(response => {
if (!/^(2|3)\d$/.test(response.status)) {
switch (response.status) {
case 401: //當前請求需要用戶驗證(一般是未登錄)
break;
case 403: //服務器已經理解請求,但是拒絕執行他(一般是TOKEN過期)
localStorage.removeItem('token');
//跳轉的登錄頁面
break;
case 404: //請求失敗,請求所希望的到的資源未被在服務器上發現
break;
}
}
return response.json()
}).catch(error => {
if (!window.navigator.onLine) {
//網路斷開了,可以讓其跳轉到斷網頁面
return;
}
return Promise.reject(error);
})
}
api的集中式管理
將模塊介面放在一個檔案中集中管理

例如 user.js
import Axios from "../utile/Axios"
//匯入封裝好的axios
/*
* 用戶頁面的所有介面
* 獲得用戶資訊
*/
export const GetUserInfo = () => {
return new Promise((resolve, reject) => {
Axios.get('/member/ajax_login.php')
.then(res => resolve(res))
.catch(err => reject(err))
})
}
/*
* 用戶退出
*/
export const Exit = () => {
return new Promise((resolve, reject) => {
Axios.post("/member/index_login.php", { dopost: 'exit' })
.then(res => resolve(res))
.catch(err => reject(err))
})
}
/*
* 用戶頁面頭部資訊
*/
export const GetUserList = () => {
return new Promise((resolve, reject) => {
Axios.get('http://www.xingzhuang.com/user/list')
.then(res => resolve(res))
.catch(err => reject(err))
})
}
/*
* 用戶下方產品串列
*/
export const getUserGoodsList = () => {
return new Promise((resolve, reject) => {
Axios.post('/html/recommend/getRecommendGoodsList', { siteId: 3, pageSize: 20, pageNum: 1 }
//pageNum為引數
).then(res => resolve(res))
.catch(err => reject(err))
})
}
在api.js檔案中進行集中匯入
/*
* 專案介面的唯一入口
*/
import { GetUserInfo, Exit, GetUserList, getUserGoodsList } from './user'
import { Category, GetMan, GetSelectind } from './cat'
export default {
GetUserInfo,
Exit,
GetUserList,
getUserGoodsList,
Category,
GetMan,
GetSelectind
}
可以在main.js中匯入
import api from '../src/api/api'
Vue.prototype.$api = api
如果此時想在用戶模塊處使用Exit方法,只需要
this.$api.Exit()
極大有利于介面管理的便捷性
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/96758.html
標籤:AI
