javascript请求封装

背景

很多人在写前端代码的时候,都不做请求封装,这样容易出现的情况是,假设在一个项目中,有100个页面,每个页面都需要向服务器发送请求,来完成数据的交互,突然有一天,产品的哥们说,咱们得加个请求的验证,给请求交互的data里,加一个加密的数据,来保证数据的安全性,如果未进行封装的话,这100个页面中,每个请求都需要改一次,这就是个很庞大的工程,所以,我们在开始写代码的时候,对请求的封装,是一个很重要的设计

理解

所谓

操作

我们以Vue项目为例,使用vue-cli搭建项目,使axios来发送请求

文件结构如下

my-projext
    |-node_modules
    |-public
    |-src
        |-assets
        |-components
        |-router
        |-store
        |-views
        |-App.vue
        |-main.js
    |-package.json

方法一:使用单独的文件来进行封装

首先,在src下新建一个文件夹api并新建一个api.js文件

my-projext
    |-node_modules
    |-public
    |-src
+       |-api
+           |-api.js
        |-assets
        |-components
        |-router
        |-store
        |-views
        |-App.vue
        |-main.js
    |-package.json

api.js添加如下内容

const apiUrl = 'https://www.yoursite.com/api/';
const axios = require('axios');

export function request(options = {}) {
    axios[options.methods](
        apiUrl+options.url, 
        options.data
    ).then(options.success)
    .catch(options.fail)
}

经过这样的封装后,在页面中使用,就变成了

page中

import {request} from '@/api/api.js';
export default {
    data(){
        return {}
    },
    methdos:{
        getData(){
            request({
                url:"getData",
                data:{
                    param_1:'入参数据'
                },
                success:(res)=>{
                    console.log('成功回调')
                }
            })
        }
    }
}

也可以在main.js中进行统一引入,然后注入到Vue.prototype中,这样就不用单独页面进行单独引入了

//main.js
import {request} from '@/api/api.js';
Vue.prototype.$request = request;


//Page中使用
this.$request({
    url:'xxxxxx'
})

这样的话,如果想在请求前增加请求拦截,只需要在公共方法中,增加一个拦截即可

    const apiUrl = 'https://www.yoursite.com/api/';
    const axios = require('axios');
+   const userData = require('@/api/userData.js');//引入放置用户信息的公共文件

    export function request(options = {}) {
+       options=beforeRequest(options)
        axios[options.methods](
            apiUrl+options.url, 
            options.data
-       ).then(options.success)
+       ).then((res)=>{
+           res=beforeResponse(res)
+           options.success&&options.success(res)
+       })
        .catch(options.fail)
    }

+   export function beforeRequest(options = {}) {//请求前拦截的地方
+       options.header = options.header||{}
+       options.header.token = userData.token;
+       return options
+   }

+   export function beforeResponse(res = {}) {//收到相应后拦截的地方
+       if(res.header.status==200){
+           if(res.data.resCode==0){
+               //业务成功逻辑
+           }else{
+               //业务失败逻辑
+           }
+           return res.data;//例如,只将回调中的data交给业务,而在拦截器里统一处理状态
+       }else{
+           alert("网络错误")
+           return res
+       }
+   }

方法二:Vuex中进行封装

我们将请求及请求拦截器,单独放置在vuex中的一个module

my-projext
    |-node_modules
    |-public
    |-src
-       |-api
-           |-api.js
        |-store
+           |- modules
+               |-api.js
            |- index.js
        |-assets
        |-components
        |-router
        |-views
        |-App.vue
        |-main.js
    |-package.json

api.js中的代码为

const axios = require('axios');
export default {
	state: {
		apiUrl:'https://www.yoursite.com/api/'
	},
	mutations: {

    },
    actions: {
        request({state,commit,dispatch},options={}){//请求方法
           this.dispatch('beforeRequest',options).then((options)=>{
                axios[options.methods](
                    apiUrl+options.url, 
                    options.data
                ).then((res)=>{
                    return Promise.resolve(res)
                }).catch(options.fail)
            }).then((res)=>{
                return this.dispatch('beforeRequest',options)
            })
        },
        beforeRequest({state,commit,dispatch},options={}){//请求前拦截
            options.header = options.header||{}
            options.header.token = this.state.userData.token;
            return Promise.resolve(options)
        },
        beforeResponse({state,commit,dispatch},res = {}) {//收到相应后拦截的地方
           if(res.header.status==200){
               if(res.data.resCode==0){
                   //业务成功逻辑
               }else{
                   //业务失败逻辑
               }
               return Promise.resolve(res.data);//例如,只将回调中的data交给业务,而在拦截器里统一处理状态
           }else{
               alert("网络错误")
               return Promise.reject(res)
           }
        }
    }
}

Page中的代码为

    import {request} from '@/api/api.js';
    export default {
        data(){
            return {}
        },
        methdos:{
            getData(){
                this.$store.dispatch('request',{
                    url:"getData",
                    data:{
                        param_1:'入参数据'
                    },
                    success:
                }).then((res)=>{
                    console.log('成功回调')
                }).catch(()=>{
                    console.log('失败回调')
                })
            }
        }
    }

更多内容在 小寒大人的前端经验分享 更新

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值