fetch网络封装

import qs from 'qs'

// 根据环境变量进行接口区分

let baseURL = ''
let baseURLArr = [{
    
    
    type: 'development',
    url: 'http://101.200.90.125:9000'
},{
    
    
    type: 'test',
    url: 'www.test.com'
},{
    
    
    type: 'production',
    url: 'www.production.com'
}]

baseURLArr.forEach(item => {
    
    
    if(process.env.NODE_ENV === item.type) {
    
    
        baseURL = item.url
    }
})

export default function request(url,options = {
    
    }){
    
    
    // 自己写的url 拼接上公共的
    url = baseURL + url
    // get系列请求处理
    //如果没有设置请求方式,默认为get
    !options.method? options.method = 'GET' : null

    // 如果设置了请求方式,判断当前有没有问号,有问号就用&符号拼接
    // 没有问号,就用问号拼接传递参数
    // options.hasOwnProperty('params') 似乎被禁用
    if(Object.prototype.hasOwnProperty.call(options,'params')){
    
    
        if(/^(GET|DELETE|HEAD|OPTIONS)$/i.test(options.method)){
    
    
            const ask = url.includes('?') ? '&' : '?'
            url += `${
      
      ask}${
      
      qs.stringify(options.params)}`
        }
        // params 不是fetch 自带的有效参数,要从传递过来options删除,是让用户传进来
        // 用完过后移除
        delete options.params
}

// 合并配置项

options = Object.assign({
    
    
    // 是否允许跨域携带资源凭证same-origin同源可以 omit都拒绝
    Credentials: 'include',
    // 设置请求头
    headers: {
    
    }
},options)
options.headers.Accept = 'application/json'

// token校验
const token = localStorage.getItem('token')
token && (options.headers.Authorization = token)

// post 请求处理
if(/^(POST|PUT)$/i.test(options.method)) {
    
    
    !options.type? options.type = 'urlencoded' : null
    if(options.type === 'urlencoded') {
    
    
        options.headers['Content-Type'] = 'application/X-www-form-urlencoded'
        options.body = qs.stringify(options.body)
    } 
    if(options.type === 'json') {
    
    
        options.headers['Content-Type'] = 'application/json'
        options.body = JSON.stringify(options.body)
    }
}

//开始发送请求
return fetch(url,options).then(response => {
    
    
    // 返回的结可能是非200的状态码
    if(!/^(2|3)\d{2}$/.test(response.status)) {
    
    
        switch(response.status) {
    
    
            case 401:     //当前用户需要验证(一般是未登陆)
                break    //一般可以弹出遮盖层,或者回到登陆页面
            case 403:     // 服务器理解请求,但是拒绝执行,一般是token,session过期
                localStorage.removeItem('token') 
                break
            case 404:     // 找不到页面(请求失败,资源在服务器上未找到),可以给一个友好的提示
                break     
       }
       return Promise.reject(response)
    }
    return response.json()
}).catch(error =>{
    
    
    // 客户端断网处理
    if(!window.navigator.onLine) {
    
    
        return
    }
    return Promise.reject(error)
})
}

使用

import fetch from './fetch'

function getFetchTestData(){
    
    
    return fetch('/paper/type/all')
}

export default {
    
    
    getFetchTestData
}

api

//定义数据请求的唯一入口,可以按大板块来分
import testData from './testData'
import fetchData from './testFetch'

export default {
    
    
    testData,
    fetchData
}

调用

<template>
  <div class="hello">
  </div>
</template>

<script>
import api from '../api/api'
export default {
    
    
  name: 'HelloWorld',
  props: {
    
    
    msg: String
  },
  methods: {
    
    
  },
  mounted () {
    
    
    // fetch方法
    // console.log(this.$api.fetchData.getFetchTestData());
    this.$api.fetchData.getFetchTestData().then(res => {
    
    
      console.log('fetch', res);
    })
    // // 原型链全局定义$api 方法  测试
    // this.$api.testData.getTestData().then(res => {
    
    
    //   console.log(res);
    // });
    // // 引入api 方式调用接口 测试
    // api.testData.getTestData().then(res => {
    
    
    //   console.log(res);
    // });
  }
}
</script>
<style scoped>
</style>

猜你喜欢

转载自blog.csdn.net/Jonn1124/article/details/114265566