vue进阶 - Axios安装及使用

基础入门文档建议直接查看Axios中文文档,这样能少走很多弯路
Axios中文文档

封装请求

在请求或响应被 then 或 catch 处理前拦截它们

import axios from 'axios';

// axios 配置
var instance = axios.create({
    headers:{
        'Content-Type': 'application/json',
    },
    timeout: 30000,
    baseURL: '',   //接口请求地址
})

//拦截重复请求
let pending = []; //声明一个数组用于存储每个ajax请求的取消函数和ajax标识
let cancelToken = axios.CancelToken;
let removeRepeatUrl = (config) => {
    let comValue = config.method == 'get' ? qs.stringify(config.params) : qs.stringify(config.data);
    for(let p in pending){
        if(pending[p].u === config.url + '&' + config.method + '&' + comValue) { //当前请求在数组中存在时执行函数体
            pending[p].f();         //执行取消操作
            pending.splice(p, 1);   //把这条记录从数组中移除
        }
    }
}
let saveRepeatUrl = (config) =>{
    let comValue = config.method == 'get' ? qs.stringify(config.params) : qs.stringify(config.data);
    console.log(comValue)
    config.cancelToken = new cancelToken((c)=>{
        pending.push({ u: config.url + '&' + config.method + '&' + comValue, f: c });  // 自定义唯一标识
    });
} }
}

// 添加请求拦截器
instance.interceptors.request.use(config => {
    // 在发送请求之前做些什么,比如传token
    removeRepeatUrl(config);       //在一个ajax发送前执行一下取消操作
    saveRepeatUrl(config);         //保存请求地址
    return config
}, error => {
    // 对请求错误做些什么
    console.log(error) // for debug
    return Promise.reject(error);
})

// 添加响应拦截器
instance.interceptors.response.use(response => {
    removeRepeatUrl(response.config);        //执行取消操作,把已经完成的请求从pending中移除
    // 对响应数据做点什么
    const res = response.data;
    //对错误代码做处理
    return response;
}, error => {
    // 对响应错误做点什么
    console.log('err' + error)// for debug
    return Promise.reject(error);
});

export default instance;

/**
 * post 请求方法
 * @param url
 * @param data
 * @returns {Promise}
 */
export function post(url, data = {}) {
    return new Promise((resolve, reject) => {
        instance.post(url, data).then(response => {
            //对接口错误码做处理
            resolve(response.data);
        }, err => {
            reject(err);
        })
    })
}

/**
 * get 请求方法
 * @param url
 * @param data
 * @returns {Promise}
 */
export function get(url, data = {}) {
    return new Promise((resolve, reject) => {
        instance.get(url, {
            params: data
        })
        .then(response => {
            resolve(response);
        })
        .catch(err => {
            reject(err)
        })
    })
}

/**
 * 封装所有请求
 * @param methed
 * @param url
 * @param data 
 * @param headers
 * @returns {Promise}
 */
export function request(methed,url, data = {},headers) {
    return new Promise((resolve, reject) => {
        instance({
            method: methed || 'post',
            url:url,
            params: methed === 'get' ? data :'',
            data: methed !== 'get' ?  data :'',
            headers: headers || {'Content-Type':'application/json'},
        })
        .then(response => {
            //对接口错误码做处理
            resolve(response.data);
        })
        .catch(err => {
            reject(err)
        })
    })
}

调用方式

在 main.js文件中引用
import {post} from './utils/http'
Vue.prototype.$post = post;

最好将项目所有接口请求放在一个文件中,方便管理

新建文件api.js
import {request} from './axios.js'
//用户登录接口
export function userLogin(data){
    return request('post','接口地址',data);
}

在其他页面引用
import {userLogin} from './api.js'
userLogin({}).then(res=>{
    
});

axios跨域

方法一
在config的index.js文件中的dev属性中添加一个属性proxyTable:

proxyTable{
    '/api':{
        target:"URL",
        changeOrigin:true,
        pathRewrite:{
               '^/api':""
        }
    }
}

然后在axios里面访问 /api/xxx 就可以成功访问了这种方式只能本地测试环境运行,对正式环境无效(需要配置环境生效)
方法二:CORS(跨域资源共享)方案解决的跨域问题
跨域资源共享 CORS 详解

拦截重复请求

请看上面封装的请求代码(掩耳盗铃,只是拦截了服务端的响应,但是还是发了请求!!!!)

碰到的问题:
请求并没有真正取消,数据还是给发送到服务器了,所以取消请求不是真的取消请求?
正常情况下客户端发送的请求服务器是会接收到然后做处理的。而所谓的abort,是指不接收请求的响应数据而不是拦截。因此某种意义上对于get类的请求
来说是有效的,但是对post类请求不行。
http请求是基于tcp的,abort取消的是http层面的请求,如果abort的时候,请求已经到达tcp层面了最终是还会到达服务器端的,只是不会再接收服务端的
响应了
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容