博客地址: https://ainyi.com/71
基于 Promise 的 HTTP 请求客户端, 可同时在浏览器和 Node.JS 中使用
vue2.0 之后, 就不再对 vue-resource 更新, 而是推荐使用 axios, 本项目也是使用 axios
功能特性
在浏览器中发送 XMLHttpRequests 请求
在 node.JS 中发送 http 请求
支持 Promise API
拦截请求和响应
转换请求和响应数据
取消请求
自动转换 JSON 数据
客户端支持保护安全免受 CSRF/XSRF(跨站请求伪造) 攻击
封装使用
建议拆分三个文件
- src
- -> service
- ---->axios.JS (axios 配置, 拦截器, 统一 url)
- ---->index.JS (接口方法, 里面调用 API 方法, 供页面级调用)
- ---->API
- ------->index.JS(API 方法, 里面调用后端提供的接口, 供接口方法调用)
axios.JS 基本配置
- 'use strict';
- import axios from 'axios';
- // 自动识别接口使用开发环境地址 (开发环境地址做了 proxyTable 代理, 故设置为空) 或线上地址
- axios.defaults.baseURL = process.env.NODE_ENV === 'production' ? process.env.API_ROOT : '';
- // 开发环境直接打包测试
- // axios.defaults.baseURL = '';
- axios.interceptors.request.use(config => {
- return config;
- }, error => {
- console.log(error);
- return Promise.reject(error);
- });
- axios.interceptors.response.use(res => {
- const apiRes = res.data;
- return apiRes;
- }, async error => {
- console.dir(error);
- return Promise.reject(error);
- });
- export default axios;
API/index.JS 调用后端提供的接口
- import Ax from '@/service/axios';
- import qs from 'qs';
- export default {
- fetchBlog (reqData) {
- return Ax.get('/krryblog/blog/getBlog', {params: reqData});
- },
- addBlog (reqData) {
- return Ax.post('/krryblog/blog/addBlog', qs.stringify(reqData));
- },
- updateBlog (reqData) {
- return Ax.post('/krryblog/blog/updateBlog', qs.stringify(reqData));
- },
- deleteBlogCover (id, reqData) {
- return Ax.post(`/krryblog/blog/deleteBlogCover/${id}`, qs.stringify(reqData));
- },
- };
index.JS 接口方法(调用 API)
- import API from './api';
- export async function getBlog(reqData) {
- let res = await API.fetchBlog(reqData);
- return res;
- },
- export async function addBlog (reqData) {
- let res = await API.addBlog(reqData);
- return res;
- },
- export async function updateBlog (reqData) {
- let res = await API.updateBlog(reqData);
- return res;
- },
- export async function deleteBlogCover (id, reqData) {
- let res = await API.deleteBlogCover(id, reqData);
- return res;
- },
页面调用
接下来就可以愉快地在页面调用了
- import { getBlog } from '@/service'
- export default {
- data() {
- return {
- tableData: [],
- pageIndex: 1,
- pageSize: 9
- }
- },
- created() {
- this.getList();
- },
- methods: {
- async getList() {
- let { result } = await getBlog({
- pageIndex: this.pageIndex,
- pageSize: this.pageSize
- });
- this.tableData = result.data;
- },
- }
axios 执行多个并发请求
- async getList() {
- let resArr = []
- for (let val of this.arrId) {
- // push 请求
- resArr.push(queryPropertyValue({ id: val }))
- }
- this.tableData = []
- Promise.all(resArr).then(res => {
- for (let val of res) {
- let vals = val.result.propertyValues
- // 每个请求的结果 push 到 tableData
- vals.forEach(item => this.tableData.push(item))
- }
- })
- },
或者直接在 axios 写 promise all
- // 根据 id 获取某一条商品数据
- let getDetail = (id)=>{
- return axios.get(`/detail?bid=${id}`);
- }
- // 检测登录的用户是否将此商品加入购物车
- let detectCar = (shopId,userId)=>{
- return axios.get(`/detectCar?shopId=${shopId}&userId=${userId}`);
- }
- // 获取一条商品数据, 并且检测是否加入购物车
- let getDeAll = (shopId,userId)=>{
- axios.all([
- getDetail(shopId),
- detectCar(shopId,userId)
- ]).then(axios.spread((resDetail, resCar)=>{
- // 两个请求现已完成
- // 打印两个请求的响应值
- console.log(resDetail);
- console.log(resCar);
- }));
- }
实例的方法
- axios#request(config)
- axios#get(url [,config])
- axios#delete(url [,config])
- axios#head(url [,config])
- axios#post(url [,data [,config]])
- axios#put(url [,data [,config]])
- axios#patch(url [,data [,config]])
请求配置: 只有 url 是必需的, 如果未指定方法, 请求将默认为 GET
axios 拦截特定请求
业务上经常出现这个问题, 需要拦截某些特定请求, 在该特定请求, 页面采取或不采取什么变化
研究 axios 的 request 统一拦截方法: axios.interceptors.request.use(function (config) {})
参数 config 如下:
可以发现 config.url 就是请求的接口的地址, 那么 "/" 最后的 getClassify 就是该请求的方法, 就可以通过取出该字符串来判断某些特定请求, 从而做出怎样的变化
- axios.interceptors.request.use(config => {
- // 判断请求是否是 getClassify, 如果是 getClassify, 不加载 LoadingBar
- let url = config.url;
- if (url.split('/').pop() === 'getClassify') {
- flag = false;
- } else {
- iView.LoadingBar.start();
- flag = true;
- }
- return config;
- }, error => {
- console.log(error);
- return Promise.reject(error);
- });
如何判断所有请求加载完毕
- let reqNum = 0
- axios.interceptors.request.use(function (config) {
- // 在请求发出之前进行一些操作, 每次发出请求就 reqNum++
- reqNum++
- _bus.$emit('showloading')
- return config
- }
- axios.interceptors.response.use(response => {
- // 接受请求后 reqNum--, 判断请求所有请求是否完成
- reqNum--
- if (reqNum <= 0) {
- _bus.$emit('closeLoading')
- } else {
- _bus.$emit('showloading')
- }
- })
axios 的 post 请求 相关问题
如果遇到 post 请求跨域问题, 在 webpack 配置文件可以设置 proxyTable 处理跨域问题
传送门: https://ainyi.com/27
post 请求携带参数, 需要做一次序列化: qs.stringify(reqData)
- saveNormalAds (reqData) {
- return Ax.post('/index.php?krry', qs.stringify(reqData));
- },
博客地址: https://ainyi.com/71
来源: https://www.cnblogs.com/ainyi/p/10676431.html