axios基础和封装
一、簡(jiǎn)介
axios 是一個(gè)基于Promise 用于瀏覽器和 nodejs 的 HTTP 客戶端,它本身具有以下特征:
-
從瀏覽器中創(chuàng)建 XMLHttpRequest
-
從 node.js 發(fā)出 http 請(qǐng)求
-
支持 Promise API
-
攔截請(qǐng)求和響應(yīng)
-
轉(zhuǎn)換請(qǐng)求和響應(yīng)數(shù)據(jù)
-
取消請(qǐng)求
-
自動(dòng)轉(zhuǎn)換JSON數(shù)據(jù)
-
客戶端支持防止 CSRF/XSRF
二、安裝
使用npm
//安裝 npm install axios --save ? //導(dǎo)入 import axios from "axios"使用 cdn:
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>三、axios返回的數(shù)據(jù)
-
config 請(qǐng)求的時(shí)候附帶的配置參數(shù)
-
data 后端返回的數(shù)據(jù)
-
headers 請(qǐng)求頭 里面包含發(fā)送給后端的格式 application/json;charset=UTF-8
-
request ajax請(qǐng)求
-
status 返回的狀態(tài)碼
-
statusText 返回的狀態(tài)文字
四、使用axios請(qǐng)求數(shù)據(jù)
(1)發(fā)送GET不帶參數(shù)請(qǐng)求
import axios from "axios"; export default {methods: {init(){axios.get('http://www.bufantec.com/api/douban/movie/in_theaters').then(function (response) {console.log(response);}).catch(function (error) {console.log(error);});}},created () {this.init();} }(2)get帶參數(shù)請(qǐng)求
import axios from "axios"; export default {methods: {init(){axios.get('http://www.bufantec.com/api/douban/movie/in_theaters?start=1&limit=10')// get請(qǐng)求附帶參數(shù)的另一種寫法/* axios.get('http://www.bufantec.com/api/douban/movie/in_theaters',{params:{start:2,limit:10}}) */.then(function (response) {console.log(response);}).catch(function (error) {console.log(error);});}},created () {this.init();} }?
(3)post請(qǐng)求
axios.post('http://order.gjw.com/Order_Api/GetValiCode').then(function (response) {console.log(response);}).catch(function (error) {console.log(error);});(4)post 帶參數(shù)請(qǐng)求
axios.post('http://order.gjw.com/Order_Api/GetValiCode',{Mob:18311111111,validcode:"815961",use:"regiVali"} ).then(function (response) {console.log(response);}).catch(function (error) {console.log(error);});五、axios執(zhí)行多個(gè)并發(fā)請(qǐng)求
一次執(zhí)行多次ajax請(qǐng)求 promise.all 執(zhí)行多個(gè)并發(fā)請(qǐng)求是通過(guò)axios.all完成
axios.all([function , function , ...])
baseGet(){//axios.get("url",參數(shù)).then(返回的信息)return axios.get('http://bufantec.com/api/douban/movie/in_theaters')}, basePost(){return axios.post('http://bufantec.com/api/test/user/fileList') }, getAll(){axios.all([this.baseGet(),this.basePost()]).then(res=>{console.log(res);}) }請(qǐng)求完成之后 會(huì)以數(shù)組的形式返回全部的請(qǐng)求數(shù)據(jù)
六、全局的 axios 默認(rèn)值
-
axios.defaults.baseURL 設(shè)置默認(rèn)公共請(qǐng)求地址baseURL
當(dāng)我們的項(xiàng)目里面有很多的接口時(shí) 設(shè)置默認(rèn)baseURL對(duì)后期的維護(hù)很有必要
例如 開(kāi)發(fā)環(huán)境訪問(wèn)的是開(kāi)發(fā)時(shí)的數(shù)據(jù)庫(kù) 生產(chǎn)環(huán)境訪問(wèn)的是線上數(shù)據(jù)庫(kù) 開(kāi)發(fā)和生產(chǎn)訪問(wèn)的不是一個(gè)地址
在請(qǐng)求的時(shí)候自動(dòng)的在地址前面加上設(shè)置的baseUrl
(開(kāi)發(fā)環(huán)境是本地開(kāi)發(fā)時(shí)的環(huán)境 生產(chǎn)環(huán)境是打包之后的環(huán)境)
七、設(shè)置超時(shí)時(shí)間
-
axios.defaults.timeout = 2500; 設(shè)置超時(shí)
當(dāng)后端返回?cái)?shù)據(jù)過(guò)慢時(shí)設(shè)置了超時(shí)就會(huì)自動(dòng)斷開(kāi)請(qǐng)求
八、設(shè)置請(qǐng)求頭
token是登陸的時(shí)候返回的token 如果后端讓在別的頁(yè)面請(qǐng)求數(shù)據(jù)的是附帶token
一般用戶判斷用戶是否登陸是根據(jù)token 進(jìn)行判斷的 一般把這個(gè)token存在session里面
只要把toke寫在請(qǐng)求頭里面 后端就知道我們登陸
axios.defaults.headers.common['token'] = localStorage["token"] //or //config.headers.Authorization = window.sessionStorage.getItem('token');登陸的時(shí)候保存sessionkey 然后在請(qǐng)求其他接口的時(shí)候帶上這個(gè)sessionkey sessionkey 代表用戶的身份 當(dāng)我們請(qǐng)求數(shù)據(jù)的時(shí)候帶上這個(gè)sessionkey 那么后端就知道現(xiàn)在是誰(shuí)在請(qǐng)求數(shù)據(jù) 還有些特殊的情況 登陸的時(shí)候后端會(huì)在本地設(shè)置cookie token 他會(huì)根據(jù)cookie里面的值token來(lái)判斷用戶是否登陸
axios.defaults.headers.common['sessionKey'] = 登陸時(shí)后端返回的sessionKey如果你每次請(qǐng)求接口需要驗(yàn)證,就加這個(gè),不需要驗(yàn)證那就不用加
九、axios攔截器 interceptors
頁(yè)面發(fā)送http請(qǐng)求,很多情況我們要對(duì)請(qǐng)求和其響應(yīng)進(jìn)行特定的處理;如果請(qǐng)求數(shù)非常多,單獨(dú)對(duì)每一個(gè)請(qǐng)求進(jìn)行處理會(huì)變得非常麻煩,程序的優(yōu)雅性也會(huì)大打折扣。好在強(qiáng)大的axios為開(kāi)發(fā)者提供了這樣一個(gè)API:攔截器。攔截器分為 請(qǐng)求(request)攔截器和 響應(yīng)(response)攔截器。
前端請(qǐng)求接口時(shí)首先向服務(wù)端發(fā)送請(qǐng)求的接口加參數(shù) 這個(gè)步驟稱之為request request 對(duì)象代表了一個(gè)HTTP請(qǐng)求,其具有一些屬性來(lái)保存請(qǐng)求中的一些數(shù)據(jù),比如params string,body,HTTP headers等等。
-
params get請(qǐng)求附帶的參數(shù)
-
body post請(qǐng)求附帶的參數(shù)
-
HTTP headers 提交數(shù)據(jù)類型
服務(wù)端接收到請(qǐng)求之后響應(yīng)數(shù)據(jù) 這個(gè)步驟稱之為response response里面存放的就是服務(wù)端返回給我們的數(shù)據(jù),包括狀態(tài)碼,返回的數(shù)據(jù)格式等等
axios攔截器就是對(duì)這請(qǐng)求前和返回?cái)?shù)據(jù)后的這兩個(gè)過(guò)程執(zhí)行操作
axios攔截器 開(kāi)始 類似路由守衛(wèi)
+ 請(qǐng)求攔截器
-
config里面包含請(qǐng)求的參數(shù) 如請(qǐng)求地址 請(qǐng)求類似 請(qǐng)求參數(shù)等 在請(qǐng)求的時(shí)候執(zhí)行一些操作 比如開(kāi)啟loading彈窗 可以想象成router的導(dǎo)航守衛(wèi)
+ 響應(yīng)攔截器
比如響應(yīng)數(shù)據(jù)之后進(jìn)行的操作
<script> axios.interceptors.response.use(function (config) {// 在請(qǐng)求之后做處理 如關(guān)閉loadingloadings.close();// 對(duì)返回過(guò)來(lái)的數(shù)據(jù)進(jìn)行過(guò)濾操作return config.data; }, function (error) {// 對(duì)請(qǐng)求失敗做處理loadings.close();return Promise.reject(error); }); </script>十、proxy跨域
在vue-cli項(xiàng)目根路徑下新建一個(gè)vue.config.js文件:
module.exports={devServer:{proxy:{// "/video":{// target:'https://www.bilibili.com',// changeOrigin:true// }//"/5a1Fazu8AA54nxGko9WTAnF6hhy":{// target:'https://sp0.baidu.com',//changeOrigin:true//}"/ajax":{target:'https://m.maoyan.com', //代理地址changeOrigin:true}}} } ?然后在組件中發(fā)送請(qǐng)求:
getMove(){axios.get("/ajax/movieOnInfoList?token=&optimus_uuid=91964AE05B9611EB9993CF30142BEF43833191D4364E42FFBA29B34F6B04A0E3&optimus_risk_level=71&optimus_code=10").then(res=>{console.log(res)}) }十一、axios封裝
(1)我們可以在components文件夾中新建一個(gè)文件夾request,然后新建http.js文件,來(lái)封裝axios
import axios from 'axios'; import router from '../router/index.js'; //import store from '../store/index'; import { Toast } from 'vant'; ? /** * 提示函數(shù) * 禁止點(diǎn)擊蒙層、顯示一秒后關(guān)閉*/ const tip = msg => { ? ?Toast({ ? ? ? ?message: msg, ? ? ? ?duration: 1000, ? ? ? ?forbidClick: true ? ?}); } /** * 跳轉(zhuǎn)登錄頁(yè)* 攜帶當(dāng)前頁(yè)面路由,以期在登錄頁(yè)面完成登錄后返回當(dāng)前頁(yè)面*/ // <router-link :to=""></router-link> ? ? const toLogin = () => {router.replace({path: '/login', ? ? ? ?query:{ //$route//$router.currentRoute:當(dāng)前路由的路由信息對(duì)象,包含了當(dāng)前匹配路由的信息redirect: router.currentRoute.fullPath}}); } ? /** * 請(qǐng)求失敗后的錯(cuò)誤統(tǒng)一處理 * @param {Number} status 請(qǐng)求失敗的狀態(tài)碼*/ const errorHandle = (status, other) => {// 狀態(tài)碼判斷switch (status) {// 401: 未登錄狀態(tài),跳轉(zhuǎn)登錄頁(yè)case 401:toLogin();break;// 403 token過(guò)期// 清除token并跳轉(zhuǎn)登錄頁(yè)case 403:tip('登錄過(guò)期,請(qǐng)重新登錄');localStorage.removeItem('token');// store.commit('loginSuccess', null);setTimeout(() => {toLogin();}, 1000);break;// 404請(qǐng)求不存在case 404:tip('請(qǐng)求的資源不存在'); break;default:console.log(other); ? }} ? // 創(chuàng)建axios實(shí)例 var instance = axios.create({ timeout: 1000 * 12}); // 設(shè)置post請(qǐng)求頭 instance.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'; /** * 請(qǐng)求攔截器 * 每次請(qǐng)求前,如果存在token則在請(qǐng)求頭中攜帶token */ instance.interceptors.request.use( ? ?config => { ? ? ? ?// 登錄流程控制中,根據(jù)本地是否存在token判斷用戶的登錄情況 ? ? ? ?// 但是即使token存在,也有可能token是過(guò)期的,所以在每次的請(qǐng)求頭中攜帶token ? ? ? ?// 后臺(tái)根據(jù)攜帶的token判斷用戶的登錄情況,并返回給我們對(duì)應(yīng)的狀態(tài)碼 ? ? ? ?// 而后我們可以在響應(yīng)攔截器中,根據(jù)狀態(tài)碼進(jìn)行一些統(tǒng)一的操作。 ? ? ? ?// const token =// store.state.token; ? const token =localStorage.getItem("token")token && (config.headers.Authorization = token); ? ? ? ?return config; ? ?}, ? ?error => Promise.error(error)) ? // 響應(yīng)攔截器 instance.interceptors.response.use( ? ?// 請(qǐng)求成功res => res.status === 200 ? Promise.resolve(res) : Promise.reject(res), ? ?// 請(qǐng)求失敗error => {const { response } = error;if (response) {// 請(qǐng)求已發(fā)出,但是不在2xx的范圍 errorHandle(response.status, response.data.message);return Promise.reject(response);} else {// 處理斷網(wǎng)的情況// eg:請(qǐng)求超時(shí)或斷網(wǎng)時(shí),更新state的network狀態(tài)// network狀態(tài)在app.vue中控制著一個(gè)全局的斷網(wǎng)提示組件的顯示隱藏// 關(guān)于斷網(wǎng)組件中的刷新重新獲取數(shù)據(jù),會(huì)在斷網(wǎng)組件中說(shuō)明// store.commit('changeNetwork', false);//服務(wù)器連結(jié)果都沒(méi)有返回//返回瀏覽器的聯(lián)網(wǎng)狀態(tài)。正常聯(lián)網(wǎng)(在線)返回 true,不正常聯(lián)網(wǎng)(離線)返回 falseif(!window.navigator.onLine){return; ? }router.push("/err")return Promise.reject(error);}} );export default instance;(2)在新建一個(gè)base.js文件,放置基礎(chǔ)地址(公共地址).有的大型項(xiàng)目基礎(chǔ)地址baseURL不止一個(gè)。
/*** 接口地址的管理* 基礎(chǔ)地址管理* 一個(gè)網(wǎng)站有可能有多個(gè)基礎(chǔ)公共地址* */ const base = { ? ?//sq: 'https://xxxx111111.com/api/v1', ? ?//bd: 'http://xxxxx22222.com/api'bufan:'http://bufantec.com/api',zhubaba:'https://api.zhubaba.cn/user' } ? export default base;(3)新建一個(gè)bufan.js文件放置不凡系列接口
/***不凡豆瓣電影接口系列* move模塊接口列表*/ ? import base from './base.js'; // 導(dǎo)入公共請(qǐng)求頭接口域名列表 import axios from './http.js'; // 導(dǎo)入http中創(chuàng)建的axios實(shí)例 import qs from 'qs'; // 根據(jù)需求是否導(dǎo)入qs模塊 ? const move = { ? ?//電影250接口列表 ? ?move(params) { ? ? ? ?return axios.get(`${base.bufan}/douban/movie/top250`,{params}); ? ?}, ? ?// 電影詳情列表 ? ?moveDetail (id) { ? ? ? ?return axios.get(`${base.bufan}/douban/movie/subject`,{id}); ? ?},// 登錄接口 ? ?login(params) { ? ? ? ?// return axios.post(`${base.sq}/accesstoken`, qs.stringify(params)); ? ?},//獲取圖片接口列表postgetPicAPI(params){return axios.post(`${base.bufan}/test/user/fileList`, qs.stringify(params))}// 其他接口………… } ? export default move(4)新建一個(gè)zhubaba.js文件,放置祝爸爸系列接口
//豬爸爸系列相關(guān)接口import base from "./base.js";import axios from "./http.js";const zhu={getLogin(params){return axios.post('https://api.zhubaba.cn/user/login',params)},getInfo(){return axios.post('https://api.zhubaba.cn/user/getInfo');}}(5)目前我們有兩個(gè)基礎(chǔ)接口地址,分別是bufan.js和zhubaba.js如果日后有需要可以在加。現(xiàn)在我們把所有接口模塊匯總,放在一個(gè)出口文件中。新建exports.js文件
/** * api接口的統(tǒng)一出口*/ // 電影模塊接口 import moveAPI from './bufan.js'; import zhuAPI from './zhubaba.js' // 其他模塊的接口…… ? // 導(dǎo)出接口 //export default { ? ?// moveAPI,//zhuAPI// …… //} ? export default {moveAPI,zhuAPI } ?(6)基本工作準(zhǔn)備好了,我們可以使用了。在使用之前我們需要確保項(xiàng)目中有vue-router、vant、vue、axios、qs等第三方包。
接下來(lái)新建一個(gè)Err.vue組件,用來(lái)做斷網(wǎng)處理。然后新建一個(gè)任意組件,用來(lái)請(qǐng)求我們封裝好的接口
<template><div><h3>不凡電影接口系列</h3><button @click="getmovies">點(diǎn)擊獲取電影top250</button><button @click="getPicList">獲取圖片列表</button></div> </template> ? <script>import allAPI from "../request/exports.js"export default {data(){return {params:{limit:5,start:1}}},methods:{getmovies(){allAPI.moveAPI.move(this.params).then(res=>{console.log(res);})},getPicList(){allAPI.moveAPI.getPicAPI(this.params).then(res=>{console.log(res);})}}} </script> ? <style> </style>測(cè)試ok。axios的封裝方便我們開(kāi)發(fā)和維護(hù)。
總結(jié)
以上是生活随笔為你收集整理的axios基础和封装的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 移动端像素概念,viewport,适配
- 下一篇: 01ts简介和相关配置