• 【Axios学习 二】一文通透Axios跨域和封装


    目录

    一、跨域

    1.1 ProxyTable

    1. 找到 config/index.js 文件中的 proxyTable:{} 将其修改

    2. 找到 config/dev.env.js 文件,配置BASE_URL

    3. 找到 config/prod.env.js 文件,配置BASE_URL

    4. 配置 axios 的基础域名

    二、封装

    1.1 条件准备

    2.2 axios封装(单域名)


    一、跨域

    因为在Vue的开发阶段,基本都是用webpack打包编译,需要node环境本地运行,因而运行的域名为本地的localhost,这个时候调用后端接口就涉及到跨域的问题了。

    1.1 ProxyTable

    vue 的 proxyTable 是用于开发阶段配置跨域的工具,可以同时配置多个后台服务器跨越请求接口,其真正依赖的npm包是 http-proxy-middleware, 在GitHub上拥有更丰富的配置,可以按需配置

    在不考虑后端CROS跨域方案的情况下,前端配置ProxyTable实现跨域请求的用法如下:

    1. 找到 config/index.js 文件中的 proxyTable:{} 将其修改

    1. proxyTable: {
    2. '/api': {
    3. target: 'https://tasst.sinoxk.cn', // 这个是你要代理的地址(开发阶段接口地址)
    4. changeOrigin: true, //跨域需要加上这个
    5. pathRewrite: {
    6. '^/api': '' //可以理解为用 / api代表target里的地址
    7. }
    8. }
    9. }

    proxyTable支持配置多个接口:

    1. proxyTable: {
    2. '/api': {
    3. target: 'https://tasst.sinoxk.cn', // 这个是你要代理的地址(开发阶段接口地址)
    4. changeOrigin: true, //跨域需要加上这个
    5. pathRewrite: {
    6. '^/api': '' //可以理解为用 / api代表target里的地址
    7. }
    8. },
    9. '/service': {
    10. target: 'https://tasst.sinoxk.cn', // 这个是你要代理的地址(开发阶段接口地址)
    11. changeOrigin: true, //跨域需要加上这个
    12. pathRewrite: {
    13. '^/service': '' //可以理解为用 / api代表target里的地址
    14. }
    15. }
    16. }

    2. 找到 config/dev.env.js 文件,配置BASE_URL

    1. module.exports = merge(prodEnv, {
    2. NODE_ENV: '"development"',
    3. BASE_URL:'"/api"' //开发环境域名
    4. })

    3. 找到 config/prod.env.js 文件,配置BASE_URL

    1. module.exports = {
    2. NODE_ENV: '"production"',
    3. BASE_URL:'"https://asst.sinoxk.com"' //生产环境保持正式域名
    4. }

    4. 配置 axios 的基础域名

    axios.defaults.baseURL = process.env.BASE_URL

    修改完所有的配置文件后,要注意,需要重启下环境

    npm run dev / npm run start 

    二、封装

    在日常项目开发过程中,在和后台交互获取数据的时候,我们都需要使用到网络库,通常在vue的项目中 ,使用的是 axios 库 ,在此基于自身项目业务,做一个二次封装。

    1.1 条件准备

    在UI轻提示组件上,选定的是 vant 库中的 Toast 组件(Vant文档),可按实际需要选定具体要使用的UI框架

    安装:

    npm install vant --save

    数据序列化,如果有实际需要的项目,可以使用qs,在这里做一个简单的介绍

    安装:

    npm install qs --save

    qs.stringify和JSON.stringify的使用和区别:

    qs.stringify()将对象 序列化成URL的形式,以&进行拼接

    JSON.stringify 是将对象转化成一个json字符串的形式

    用法:

    1. var a = {name:'xiaoming',age:10}
    2. qs.stringify(a); //log: 'name=xiaoming&age=10'
    3. JSON.stringify(a) //log: '{"name":"hehe","age":10}'

    基于底层配置和业务接口分离,在src目录中会新建文件夹 httpServer,同时新建立 ajax.js 和 api.js 文件

    ajax.js: axios的二次封装,作为基础网络库,添加基础的配置
    
    api.js: 管理项目实际业务基础接口的输出,以及返回响应数据的处理
    

    在日常项目模块中,基于多人开发,当然可以在api.js的基础上,可以根据功能模块实现业务拓展延伸,比如

    1. 小明负责list模块业务
    2. 新建api-list.js,并导入api.js ....
    3. //api-list.js文件中:
    4. import api from './api'
    5. export default {
    6. getList(url,params){
    7. api.get(url,params)
    8. }
    9. }

    对于个别项目,可能存在多个域名配置的情况下, 可以重新建立 base.js , 来管理多个接口域名

    base.js:

    1. /**
    2. * 接口域名的管理
    3. */
    4. const base = {
    5. sq: 'https://xxxx111111.com/api/v1',
    6. bd: 'http://xxxxx22222.com/api'
    7. }
    8. export default base;

    2.2 axios封装(单域名)

    src/main.js文件:

    1. import Vue from 'vue'
    2. import App from './App'
    3. import router from './router'
    4. import Api from './httpServer/api'
    5. //挂载到vue的全局属性上
    6. Vue.prototype.$https = Api
    7. Vue.config.productionTip = false
    8. new Vue({
    9. el: '#app',
    10. router,
    11. components: { App },
    12. template: ''
    13. })

    src/httpServer/ajax.js文件:

    1. import axios from 'axios'
    2. import {Toast} from 'vant'
    3. const ajax = axios.create({
    4. timeout:60000,
    5. baseURL:process.env.BASE_URL //基础域名
    6. })
    7. /**
    8. * 请求拦截器
    9. * 每次请求前,如果存在token则在请求头中携带token
    10. */
    11. ajax.interceptors.request.use(
    12. config => {
    13. //判断token(根据实际情况拦截)
    14. return config;
    15. },
    16. error => Promise.error(error)
    17. )
    18. /**
    19. * 响应拦截器
    20. */
    21. ajax.interceptors.response.use(
    22. // 请求成功
    23. res => res.status === 200 ? Promise.resolve(res) : Promise.reject(res),
    24. error => {
    25. const {response} = error;
    26. if (response) { // 请求已发出,但是不在2xx的范围
    27. Toast({message: response.message});
    28. return Promise.reject(response);
    29. } else {
    30. // 处理断网的情况
    31. // eg:请求超时或断网时,更新state的network状态
    32. // network状态在app.vue中控制着一个全局的断网提示组件的显示隐藏
    33. // 关于断网组件中的刷新重新获取数据,会在断网组件中说明
    34. Toast({message: '网络开小差,请稍后重试'});
    35. }
    36. }
    37. )
    38. export default ajax;

    对于process.env.BASE_URL的配置,在开发环境中,需要以代理的方式进行访问:

    1. //config/dev.env.js
    2. 'use strict'
    3. const merge = require('webpack-merge')
    4. const prodEnv = require('./prod.env')
    5. module.exports = merge(prodEnv, {
    6. NODE_ENV: '"development"',
    7. BASE_URL:'"/api"' //对api进行处理
    8. })
    9. //config/prod.env.js
    10. 'use strict'
    11. module.exports = {
    12. NODE_ENV: '"production"',
    13. BASE_URL:'"https://www.xxx.com"' //生产环境不需要处理
    14. }
    15. //config/index.js
    16. ...
    17. proxyTable: {
    18. '/api': {
    19. target: 'https://tasst.sinoxk.cn',//后端接口地址
    20. changeOrigin: true,//是否允许跨越
    21. pathRewrite: {
    22. '^/api': '',//重写(接口地址带api会被替换)
    23. },
    24. }
    25. },
    26. ...

    src/httpServer/api.js文件:

    1. import ajax from './ajax'
    2. import {Toast} from 'vant'
    3. /**
    4. * 业务接口成功或者失败的情况处理
    5. *
    6. */
    7. const handleResponse = (res, success, failure) => {
    8. switch (res.code) {
    9. case 200: //成功
    10. success && success(res.data);
    11. break;
    12. case 401: //登录token失效
    13. break;
    14. default:
    15. if (failure) {
    16. failure(res);
    17. } else {
    18. Toast({message:res.msg || '请求失败,请稍后重试!'});
    19. }
    20. break;
    21. }
    22. }
    23. export default {
    24. get: function (url, params, success, failure) {
    25. ajax.get(url, {
    26. params: params
    27. }).then(res => {
    28. if (res.status == 200) {
    29. handleResponse(res.data.data, success, failure);
    30. }
    31. });
    32. },
    33. post: function (url, params, success, failure) {
    34. ajax.post(url, params).then(res => {
    35. if (res.status == 200) {
    36. handleResponse(res.data.data, success, failure);
    37. }
    38. })
    39. }
    40. }

    src/components/HelloWorld.vue文件中使用:

  • 相关阅读:
    今天是1024,获取一下纪念牌
    【RuoYi-Vue-Plus】扩展笔记 03 - 实现简单的 EasyExcel 自定义导入监听器
    自动化测试难题,验证码如何解决
    项目通用pom.xml文件模版
    SpringMVC
    Unity 安卓包激励视频广告退后台再进入APP广告消失
    大数据培训课程之RDD传递一个属性
    前端+后端项目 - 论坛信息管理系统(Web+servlet+MySQL+JDBC)
    人脸识别5.3- insightface人脸3d关键点检测源码更改,根据姿态角修正图片角度,调整向量解析值,增大识别准确度,以及返回
    java文件传输简单方法
  • 原文地址:https://blog.csdn.net/yzq0820/article/details/127564641