【javascript】axios与fetch常见封装方法

背景

  • 以前写项目从来不封装这玩意,后来发现别人写项目都这么搞,于是照着做了个axios与fetch的
  • 通过对fetch的封装,可以发现,实际发送请求就那一下,拦截器配置的实质其实就是在请求前做操作或者收到响应后做操作。我一开始听axios的拦截器以为是个多高端的东西。。。这样手写axios也就很容易搞,实际请求就是用ajax发,自己写个类然后配置拦截器即可。后面准备写一篇手写axios。

代码

  • 由于这封装多用于项目,所以我结合了webpack进行操作。webpack的配置就不说了,直接放代码。

axios.js

import axios from 'axios'
import qs from 'qs'

//配置url
switch(process.env.NODE_ENV){
    case "production"://生产自己配
        axios.defaults.baseURL = "http://127.0.0.1:8080";
        break;
    case "development":
        axios.defaults.baseURL = "http://127.0.0.1:8080";
        break; 
    default:
        axios.defaults.baseURL = "http://127.0.0.1:8080"
}

//设置超时时间
axios.defaults.timeout=10000

//设置是否允许跨域携带资源凭证
axios.defaults.withCredentials = true

//设置post请求头,告知服务器请求主体的数据格式  //很多老后台都是此格式,json也比较多。此格式跟get传参格式一样。
axios.defaults.headers['Content-Type']="application/x-www-form-urlencoded"
//不使用上面格式,data自行处理。
axios.defaults.transformRequest = data => qs.stringify(data)

//配置请求拦截器 config就是发请求的配置
axios.interceptors.request.use((config)=>{
    //查找token并带上请求
    let token = localStorage.getItem('token')
    token&&(config.headers.Authorization =token)
    return config
},err=>Promise.reject(err))


//自定义响应成功http状态码
axios.defaults.validateStatus=status=>{
    return /^(2|3)\d{2}$/.test(status)
}


//配置相应拦截器
axios.interceptors.response.use((res)=>{
    //一般只要把返回数据拿出来即可。避免每次都取数据要点data
    return res.data
},err=>{
    let {response}=err
    if(response){//有结果
        switch(response.status){
            case 401://请求需要验证
                break;
            case 403://一般为token session过期,服务器拒绝
                localStorage.removeItem(token)
                break;
            case 404:   //找不到页面
                break;
            default:
                return
        }

    }else{//服务器没返回
        if(!window.navigator.onLine){
            //断网处理  配置断网页面
            return
        }
        return Promise.reject(err)
    }
})

export default axios

fetch.js

import qs from 'qs'

let baseURL = ''
//配置url
switch(process.env.NODE_ENV){
    case "production"://生产自己配
        baseURL = "http://127.0.0.1:8080";
        break;
    case "development":
        baseURL = "http://127.0.0.1:8080";
        break; 
    default:
        baseURL = "http://127.0.0.1:8080"
}

export default function  request(url,option={}) {
    url = baseURL+url;
    !option.method?option.method='get':null
    if(option.hasOwnProperty('params')){//i表示不区分大小写,参数有可能写配置项而不是url
        if(/^(GET|DELETE|HEAD|OPTIONS)$/i.test(option.method)){
            //如果url有问号,说明这些参数是另加,用&连接,如果没有,就上问号连接
            const ask =url.includes('?')?'&':'?';
            url +=`${ask}${qs.stringify(option.params)}`
        }
        delete option.params
    }
    //合并配置
    option = Object.assign({
        crendentials:"include",//same-origin同源才可以,omit拒绝携带资源凭证
        headers:{}
    },option)
    
    const token = localStorage.getItem('token')
    token && (option.headers.Authorization=token)

    //post
    if(/^(POST|PUT)$/i.test(option.method)){
        !option.type?option.type='urlencoded':null
        //判断类型加上请求头
        if(option.type==='urlencoded'){
            option.headers['Content-Type']='application/x-www-form-urlencoded'
            option.body = qs.stringify(option.body)
        }
        if(option.type==='json'){
            option.headers['Content-Type']='application/json'
            option.body = JSON.stringify(option.body)
        }
    }
    return fetch(url,option).then(res=>{
        if(!/^(2|3)\d{2}$/.test(res.status)){
            switch(res.status){
                case 401://请求需要验证
                    break;
                case 403://一般为token session过期,服务器拒绝
                    localStorage.removeItem(token)
                    break;
                case 404:   //找不到页面
                    break;
                default:
                    return
            }
        }
        return res.json()
    }).catch(err=>{
        if(!window.navigator.onLine){
            //断网
            return
        }else{
            return Promise.reject(err)
        }
    })
}
  • 然后写了个api文件在index.js里导入进行测试:

api.js

import axios from './axios'
import request from './fetch'

export function login() {
    return axios.post('/post', {
        name: 'axiospost'
    })
}
export function test() {
    return request('/get', {
        method: 'get',
        params: { name: 'fetch' }
    })
}
export function fetchpost() {
    return request('/post', {
        method: 'post',
        type: 'urlencoded',
        body: {
            name: 'fetchpost'
        }
    })
}
export function axiosget() {
    return axios.get("/get", {
        params: {
            name: "axiosget"
        }
    })
}

index.js

import *as api from './api'
api.login().then((res)=>console.log(res))
api.test().then((res)=>console.log(res))
api.axiosget().then((res)=>console.log(res))
api.fetchpost().then((res)=>console.log(res))
  • 如果有同学懒得配webpack或者后端的可以使用此仓库。里面配了个基本配置,后端使用直接node运行server.js即可。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

业火之理

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值