文章目录
1 Axios简介1.1 什么是Axios?1.2 Axios的特性 2 Axios的使用2.1 Axios的安装2.2 Axios的创建2.2.1 Proxy配置代理2.2.1.1 核心代码2.2.1.2 代码解释2.2.1.3 多个跨域 2.2.2 Axios的二次封装2.2.2.1 为什么要二次封装2.2.2.2 Axios实例化2.2.2.2.1 引入2.2.2.2.2 创建axios2.2.2.2.3 配置请求拦截器2.2.2.2.4 配置响应拦截器2.2.2.2.5 暴露2.2.2.2.6 例子 2.3 Axios的直接使用2.3.1 get请求2.3.1.1 无参2.3.1.2 有参 2.3.2 Post请求2.3.3 通用(常用)2.3.3.1 无参2.3.3.2 有参 2.3.4 例子 2.4 接口统一管理2.4.1 接口统一管理的原因2.4.2 接口管理2.4.2.1 新建一个index.js文件 放置接口,引入axios2.4.2.2 编写接口方法2.4.2.3 接口全局注册
1 Axios简介
1.1 什么是Axios?
Axios 是一个基于 promise 网络请求库,作用于node.js
和浏览器中。 它是 isomorphic 的(即同一套代码可以运行在浏览器和node.js中)。在服务端它使用原生 node.js http
模块, 而在客户端 (浏览端) 则使用 XMLHttpRequests。
1.2 Axios的特性
从浏览器创建 XMLHttpRequests
从 node.js 创建 http 请求
支持 Promise API
拦截请求和响应
转换请求和响应数据
取消请求
自动转换JSON数据
客户端支持防御XSRF
2 Axios的使用
2.1 Axios的安装
npm install axios
在控制台输入 npm install axios – 回车,当看到package-lock.json的packages里面有了axios,说明引入成功
2.2 Axios的创建
2.2.1 Proxy配置代理
官方文档传送门 https://cli.vuejs.org/zh/config/#devserver-proxy
2.2.1.1 核心代码
const { defineConfig } = require("@vue/cli-service")module.exports = defineConfig({ lintOnSave: false, transpileDependencies: true, devServer: { proxy: { '/api': { target: "http://localhost:9000", //需要跨域的目标地址 pathRewrite: { '^/api': '' },//将带有api的路径重写为'' ws: true,//用于支持WebSocket changeOrigin: true,//用于控制请求头的Host }, } }})
2.2.1.2 代码解释
‘/api’:当请求地址的前缀中有该字符串时会进行跨域操作,反之则在本地请求。
前缀如localhost:8080/api/student,这里的api就是前缀。
localhost:8080/student/api,这里的api就不是前缀,student是他的前缀
target:要跨域的地址,在上图即为localhsot:5001
pathRewrite:路径重写
404错误问题:
当本地服务器以/api/student的路径请求服务器的时候,代理服务器检测到’api’需要跨域,然后如实转发。所以到达5001端口的时候,会去api/Student找自己想要的资源,但是5001端口只有Student,所以会爆404错误
使用pathRewrite,会将访问地址中的该前缀替换为:后面的字符,这里是’',所以到达5001的时候,会正确的访问Student找到自己想要的资源。
changeOrigin:用于控制请求头的Host
值为false,当在端口5001,询问这个请求从哪来的,请求会如实回答:8080。
值为true,当在端口5001,询问这个请求从哪来的,请求会撒谎:5001,你在哪我的回答就是哪。
2.2.1.3 多个跨域
如果需要多个跨域的话,只需要继续往下写即可。
2.2.2 Axios的二次封装
2.2.2.1 为什么要二次封装
请求拦截器、响应拦截器:请求拦截器可以在发送请求之前处理一些业务
当数据返回后,响应拦截器可以处理一些业务
2.2.2.2 Axios实例化
可以直接看2.2.2.2.6
2.2.2.2.1 引入
新建一个api文件,创建request.js 用于引入axios
2.2.2.2.2 创建axios
const requests = axios.create({ baseURL: '/api', timeout: 50000, });
baseURL:追加一个前缀,如你需要访问的地址是localhost:9000/api/song/SongSheet在访问的时候,你只需要写成’localhost:9000/song/SongSheet’timeout:访问超时的时间ms,超过这个时间即为访问失败 2.2.2.2.3 配置请求拦截器
// 添加请求拦截器requests.interceptors.request.use(function (config) { // 在发送请求之前做些什么,例如加入token return config; }, function (error) { // 对请求错误做些什么 return Promise.reject(error); });
这里也解决了我困惑已久的一个问题:为什么以前返回的数据没有code,只有单纯的一个数据。
我一度以为要在后端写。
如果这里返回的是config,那么就会有data,status,statusText, headers等等,如果只是返回config.data,那么你看到的就只有data数据了。
2.2.2.2.4 配置响应拦截器
requests.interceptors.response.use(function (response) { // 在接收响应时做些什么,例如跳转到登录页 return response; }, function (error) { // 对响应错误做点什么 return Promise.reject(error); });
2.2.2.2.5 暴露
如果不暴露是不能用的
export default requests;
2.2.2.2.6 例子
import axios from "axios";const requests = axios.create({ baseURL: '/api', timeout: 50000, });// 添加请求拦截器requests.interceptors.request.use(function (config) { // 在发送请求之前做些什么,例如加入token return config; }, function (error) { // 对请求错误做些什么 return Promise.reject(error); });// 添加响应拦截器requests.interceptors.response.use(function (response) { // 在接收响应时做些什么,例如跳转到登录页 return response; }, function (error) { // 对响应错误做点什么 return Promise.reject(error); }); export default requests;
2.3 Axios的直接使用
此处的requests 是2.2中axios.create()返回的值,使用前需要引入requests
2.3.1 get请求
2.3.1.1 无参
requests.get('url');
举例:如我想要访问的是localhost:9000/api/song/SongAllSheet
api在baseURL里面配置了,所以我只需要写成
requests.get('/song/SongAllSheet');
2.3.1.2 有参
/Opera/getPersonalOpera是URL,value是你参数的名字
requests.get(`/Opera/getPersonalOpera/${value}`);
2.3.2 Post请求
axios.post("url",{params:{ name:'jok', age:'18' }})
2.3.3 通用(常用)
2.3.3.1 无参
get请求methods:后面为get,post则为post
requests({url:'/Opera/getPersonalOpera',methods:'get'})
2.3.3.2 有参
此处用的是``,英文下,Tab上面的那个键
requests({url:`/Opera/getPersonalOpera/${value}`,methods:'get'})
2.3.4 例子
<template> <div class="hello"> </div></template><script>import requests from "@/api/request"export default { name: 'HelloWorld', data() { return{ Song: [], secondSong:[], thirdSong:[], } }, methods: { async getAllSongs() { let result = await requests.get('/song/SongAllSheet'); if(result.status == 200) { this.Song = result.data; } }, async getSongById(value) { let result = await requests({url:`/Opera/getPersonalOpera/${value}`,methods:'get'}) if(result.status == 200) { this.secondSong = result.data; } } }, mounted() { this.getAllSongs(); this.getSongById(1); }, }</script>
可以看到是成功拿到数据的
解决返回数据是Promise的情况
所以只需要在方法里面直接赋值即可
2.4 接口统一管理
2.4.1 接口统一管理的原因
对于较小的项目,使用时在撰写无伤大雅
对于一些比较大型项目,随意写接口,如果后端的接口稍有改动,那么维护起来非常的困难
所以把所有的接口放在一起,而且抽象成一个方法,这样使用起来不需要重复写,而且改动起来也比较方便
2.4.2 接口管理
2.4.2.1 新建一个index.js文件 放置接口,引入axios
import requests from "./request";
2.4.2.2 编写接口方法
原版
export const reqGetAllSongById = (value)=>{ return requests({url:`/Opera/getPersonalOpera/${value}`,methods:'get'});}export const reqGetAllSong = ()=>{ return requests({url:'/Opera/getPersonalOpera',methods:'get'});}
简写版
export const reqGetAllSong = ()=>requests({url:'/Opera/getPersonalOpera',methods:'get'});export const reqGetAllSongByType = (value)=> requests({url:`/Opera/getPersonalOpera/${value}`,methods:'get'});
2.4.2.3 接口全局注册
这样虽然好管理了,但是如果使用的话,还需要一一引入。
在如上位置,写如下代码
import * as API from '@/api' beforeCreate(){ Vue.prototype.$API = API; },
使用之时,前缀加上this.$API便可正常使用
<template> <div class="hello"> </div></template><script>import requests from "@/api/request"export default { name: 'HelloWorld', data() { return{ Song: [], secondSong:[], thirdSong:[], } }, methods: { async getAllSongs() { let result = await this.$API.reqGetAllSongByType(1); if(result.status==200) { this.Song = result.data; } } }, mounted() { this.getAllSongs(); }, }</script>
访问成功