1.1. Axios

Axios 是一个基于 Promise 的 HTTP 库,可以用在浏览器和 node.js 中。

Github开源地址: https://github.com/axios/axios

1.2. 安装

[!tip]

vue3不要用vue add axios安装,不然会出现各种问题,且很难解决,网上给出的解决办法就是用vue2👎

# 其他组件
vue create hello-vue
cd hello-vue
vue add element-plus
vue add router

# axios
npm install --save axios # 安装后可以在package.json中查看安装的版本

安装后在main.js中引入,参考文章:手把手教你在vue3中使用axios

import { createApp } from 'vue'
import App from './App.vue'
import installElementPlus from './plugins/element'
import router from './router'
import axios from "axios"  // 引入

const app = createApp(App).use(router)
installElementPlus(app)
app.config.globalProperties.axios = axios // 将axios挂载到全局变量,后面可以通过 this.axios 调用

app.mount('#app')

1.3. 使用

引入后就可以直接用了,注意是this.axios,因为我们给挂载到全局变量了

<template>
  <div class="about">
    <h1 @click="test">This is an about page</h1>
  </div>
</template>

<script>
export default {
  methods: {
    test() {
      this.axios.get("http://127.0.0.1:8080",{a:"b"})
      .then(res => {
        console.log(res)
      })
      .catch(err => {
        console.error(err); 
      })
    }
  },
}
</script>

用法就是getpost等,发起请求抓取数据即可,vscode装了插件都可以自动补全,比较方便

axios.request(config)
axios.get(url[, config])
axios.delete(url[, config])
axios.head(url[, config])
axios.options(url[, config])
axios.post(url[, data[, config]])
axios.put(url[, data[, config]])
axios.patch(url[, data[, config]])

更多用法参考官方文档:axios中文文档

1.4. 解决跨域问题

以某天气API http://t.weather.sojson.com/api/weather/city/101030100 为例,如果直接本地用axios发起get post请求,肯定是拿不到数据的,因为有CORS策略的限制。

image-20220617173455865

要解决这个问题,有2个方法:

1、修改后端,添加header头信任任意来源(这里肯定没权限改别人的后端,所以有第二个方法)

Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true

2、可以通过Vue的proxy来解决跨域的问题

vue.config.js文件中,加入如下内容:

也可以在main.js中配置axios.defaults.baseURL,自动加上代理的URL,减少每次写一遍代理URL的工作量

module.exports = {
  publicPath:'./',//静态资源包打包为相对路径
  outputDir:'dist',//输出文件
  devServer:{
      open:false,
      host:'0.0.0.0',
      port:8090,
      hot:true,
      proxy: {
          '/api': {
            target: 'http://t.weather.sojson.com/', // 需要请求的第三方接口地址
            changeOrigin: true, // 是否跨域:在本地会创建一个虚拟服务端,然后发送请求的数据,并同时接收请求的数据,这样服务端和服务端进行数据的交互就不会有跨域问题
            ws: true,  //是否代理 websockets
            secure: false,  //是否https接口
            pathRewrite: {  // 路径重写,
              '^/api': ''  // 替换target中的请求地址,也就是说以后你请求/api就等于请求http://t.weather.sojson.com/。
            }
          }
      },  
  }
}

然后请求内容如下:

export default {
  methods: {
    test() {
      this.axios.get("/api/api/weather/city/101030100") // 相当于http://t.weather.sojson.com/api/weather/city/101030100
      .then(res => {
        console.log(res)
      })
      .catch(err => {
        console.error(err); 
      })
    }
  },
}

最终成功拿到了数据

image-20220617174225550

1.5. 抽离配置

如果axios的配置少还好,如果配置内容多,全部写到main.js还是有点恼火,所以我们可以模仿安装element-plus.js的方法,给axios配置单独抽离到1个js文件里面,后面直接改这个配置文件即可。

  • axios.js内容如下
import axios from "axios"  // 引入

export default (app) => {
    app.config.globalProperties.axios = axios // 将axios挂载到全局变量,后面可以通过 this.axios 调用
}
  • main.js中引入
import installAxios from './plugins/axios'
installAxios(app)

后面要加什么全局配置、拦截器啥的,都直接在axios.js里面➕就行

1.6. 拦截器

可以结合上面的抽离配置一起用。有些时候要验证登陆,需要在header请求头加入自定义信息,如jwt-token,如果每一个axios发起请求的地方都去手动加一个header,那么肯定费时费力且不好维护,所以可以用到拦截器。

还有就是在响应的时候,如果要根据返回的message显示对应的内容、或者验证返回的状态码,都可以用拦截器;简而言之:axios请求前后所有重复的操作都可以抽象到拦截器中。

拦截器:在请求或响应被 thencatch 处理前拦截它们。

// 添加请求拦截器
axios.interceptors.request.use(function (config) {
    // 在发送请求之前做些什么
    return config;
  }, function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
  });

// 添加响应拦截器
axios.interceptors.response.use(function (response) {
    // 对响应数据做点什么
    return response;
  }, function (error) {
    // 对响应错误做点什么
    return Promise.reject(error);
  });
  • 1个例子(不要给所有的axios请求都带上token,最好限定一下源,不然万一开发途中有可控的URL,别人就可以抓取到token了)
import axios from "axios"  // 引入
import { ElMessage } from 'element-plus'
import router from '../router'
import api from '@/config/api'

// 添加请求拦截器
axios.interceptors.request.use(function (config) {
    // 在发送请求之前做些什么
    if(config.url.indexOf(api.frontUrl) != -1 ){ // 只有后端的URL才需要加token,避免token劫持
      if (!config.headers['token']) {
          config.headers['token'] = sessionStorage.token;
      }
    }
    return config;
  }, function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
  });

// 添加响应拦截器
axios.interceptors.response.use(function (response) {
  // 对响应数据做点什么
  if(response.request.responseURL.indexOf(api.frontUrl) != -1 ) {
    var resp = response.data
    let message = resp.message
      if (resp.code === 200) {
          ElMessage({
            message: message,
            type: 'success',
            duration: 1000,
          })
      } else {
          ElMessage({
            message: message,
            type: 'error',
            duration: 1000,
            })
      }
      // 未登录
      if (resp.code === 401) {
        router.push({ path:'/login'})
      }
  }
  return response;
}, function (error) {
  // 对响应错误做点什么
  return Promise.reject(error);
});

export default (app) => {
    app.config.globalProperties.axios = axios // 将axios挂载到全局变量,后面可以通过 this.axios 调用
}
Copyright © d4m1ts 2022 all right reserved,powered by Gitbook该文章修订时间: 2022-07-04 10:14:59

results matching ""

    No results matching ""