代理转发解决跨域问题及二次封装Axios

本文介绍了跨域问题的背景及解决方法,重点讲解了代理转发的原理与配置,并提供了在Vue项目中利用axios进行请求封装的具体实现步骤。

实现跨域的方式有以下几种:

        1、jsonp:只能处理 GET 方式的跨域,以后开发中几乎用不到

        2、CORS:一般由后端负责配置

        3、代理转发:目前在开发中,是解决跨域的主流方案

代理转发的原理:

        1、跨域:浏览器的同源策略产生跨域问题,服务器之间不存在跨域问题

        2、代理服务器向接口服务器发起请求,不存在跨域问题

        3、代理服务器 和 前端项目同源,也没有跨域问题

 

在Veu项目中,在vue.config.js文件中进行配置

配置代码如下:

 

const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true,
  devServer: {
    open: true, // 运行项目后自动打开浏览器
    host: 'localhost', // 设置运行的主机
    port: 8080, // 设置端口
    proxy: {
      // 匹配所有以api开头的的请求路径
      '/api': {
        target: 'http://xxxxxxx.cn/', // 代理目标的基准路径
        changeOrigin: true
      }
    }
  }
})

 二次封装Axios

实际开发中,我们经常有这样的需求:

  1. 开发中需要切换不同的开发环境,例如:开发环境、生产环境、测试环境

  2. 对网络请求的超时时长进行设置,例如:5 秒内没有返回数据,抛出错误

  3. 对提交数据和返回数据进行拦截,例如:给接口统一添加 token,格式化后端返回的数据

  4. 对网络请求产生的错误统一处理,例如:请求超时提示、token 失效的错误

  5. 添加 loading 效果 ...... 等等

具体实现步骤:

        在项目src目录下创建utils文件夹

        在 utils 目录下创建 request.js 文件(http.js)

        创建 request实例

        配置请求拦截器、响应拦截器

        分析和设置响应拦截器处理错误的方式

具体代码如下:

import axios from 'axios'

// 导入进度条插件(需要下包)
import Nprogress from 'nprogress'
import 'nprogress/nprogress.css'
// axios实例
const request = axios.create({
  baseURL: 'http://xxxx.cn/', // 接口基准地址
  timeout: 5000// 请求超时时间
})
// 添加请求拦截器
instance.interceptors.request.use((config) => {
  // 在发送请求之前做些什么
  Nprogress.start() //开启进度条
  return config
}, (error) => {
  // 对请求错误做些什么
  return Promise.reject(error)
})

// 添加响应拦截器
instance.interceptors.response.use((response) => {
  // 2xx 范围内的状态码都会触发该函数。
  // 对响应数据做点什么
  Nprogress.done()//结束进度条
  return response.data//返回后端提供的真正的数据
}, (error) => {
  // 超出 2xx 范围的状态码都会触发该函数。
  // 对响应错误做点什么
  // return Promise.reject(error) //让错误继续往下传递,从而触发程序员发请求时的回调函数

  alert(error.message)
  return new Promise(() => {}) //返回一个 pending 状态的 Promise 实例,中断了 Promise 链,不走程序员发请求时的回调
})
export default instance

统一管理 AJAX 请求

        在实际开发中,我们通常将所有的网络请求方法放置在 api 目录下统一管理,然后按照模块功能来划分成对应的文件,在文件中将每个接口的请求都单独导出了一个方法,例如:

// 导入封装的网络请求工具 request.js
import request from '../utils/request'

export const reqData= () => request.get('/api/xxxxxx')//请求路径

使用:

<script>
// 导入网络请求配置
import { reqDaata} from '../../api/index'

export default {
  name: 'TestPage',
  methods: {
    async proxyData() {
      // const data = await request.get('/api/product/getBaseCategoryList')
      
      const data = await reqCategoryList()
      console.log(data)
    }
  }
}
</script>

这样做的有以下几点好处:

  1. 易于维护:一个文件就是一个模块,一个方法就是一个功能,清晰明了,查找方便

  2. 便于复用: 哪里使用,哪里导入,可以在任何一个业务组件中导入需要的方法即可

  3. 语义清晰:方法名具有语义化,做到 命名即注释,语义化清晰,维护方便,

  4. 团队合作:分工合作

​​​​​​​

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值