1.1 封装Axios对象
因为项目中很多组件中要通过 Axios 发送异步请求,所以封装一个 Axios 对象。自已封装的 Axios 在后续可以使用 axios 中提供的拦截器。
1.在src目录下创建utils目录,在utils下创建request.js文件
2.内容:
import axios from 'axios' //引入axios
// 手动创建一个 axios 对象, 参考: https://github.com/axios/axios#creating-an-instance
const request = axios.create({
// 请求配置参考: https://github.com/axios/axios#request-config
// 根据不同环境设置 baseURL, 终发送请求时的URL为: baseURL + 发送请求时写URL ,
// 比如 get('/test'), 终发送请求是: /dev-api/test
// baseURL: '/dev-api',
baseURL: '/',
timeout: 5000 // 请求超时
})
export default request // 导出 axios 对象
1.2 测试封装的Axios
- 在
public下创建data.json数据文件,内容如下:
[
{"name": "小梦", "age": 18},
{"name": "小岳岳", "age": 28},
{"name": "林志玲", "age": 38}
]
2. 在src目录下创建api目录,在api目录下创建test.js文件
3. 测试请求data.json,直接请求http://localhost:8888/data.json,不用加public
// @ 代表的是 /src
// import axios from '@/utils/request'
import request from "@/utils/request";
const BASE_URL = 'http://localhost:8888'
// 测试1 调用get方式发送get请求
request.get(BASE_URL + "/data.json").then(response => {
console.log("get1", response.data);
}).catch(error => {
console.log(error);
});
// 测试2, 使用对象形式传入请求配置,如 请求url, method,param
request({
url: BASE_URL + "/db.json",
method: "get"
}).then(response => {
console.log("get2", response.data);
}).catch(error => {
console.log(error);
});
4.导出对象方式:
导出的默认对象里面是方法,方法返回值为 Promise 对象,通过它调用 then 获取响应数据
// 测试3 导出默认对象
export default {
getList(data) {
const req = request({
type: "get",
url: BASE_URL+ "/db.json",
data:data //传参过来的data
});
// console.log(req) // Promise
return req;
}
}
- 在 HelloWorld.vue中导入test.js
<script>
// 直接导入 测试1和测试2 就会执行
import testApi from '@/api/test'
//验证 测试3
export default {
created() {
// 钩子中初始化数据
this.fetchData(data)
},
methods: {
// data 参数的传递
fetchData(data) {
// 直接调用test文件中的对象,实现数据的请求
testApi.getList(data).then(response => {
console.log('get3', response.data)
}).catch(error => {
console.log(error)
})
}
},
name: "HelloWorld",
props: {
msg: String
},
};
</script>
1.3 Axios跨域问题
**什么是跨域:**前后端分离时,前端和后端API服务器可能不在同一台主机上,就存在跨域问题,浏览器限制了跨域访问。(跨域只存在于PC端) 同源策略:是指协议,域名,端口都要相同,其中有一个不同都会产生跨域。
同源策略:是指协议,域名,端口都要相同,其中有一个不同都会产生跨域。
如下面示例存在跨域:
前端页面部署在:http://localhost:8001 即本地ip端口8001上;
后端API部署在: http://localhost:8002 即本地ip端口8002上 ; 它们IP一样,但是端口不一样,所以存在跨域问题。 跨域解决: 通过代理请求的方式解决,将 API 请求通过代理服务器请求到 API 服务器。 开发环境中,在 vue.config.js 文件中使用 devServer.proxy 选项进行代理配置。
1.4 解决开发环境跨域问题
1.在vue.config.js文件中使用devServer.proxy选项进行代理配置
module.exports = {
devServer: {
port: 8888, // 端口号,如果端口号被占用,会自动提升1
host: "localhost", //主机名, 127.0.0.1, 真机 0.0.0.0
https: false, //协议
open: true, //启动服务时自动打开浏览器访问
proxy: { //代理配置
// 匹配 /dev-api 开头的请求,
'/dev-api': {
// 目标服务器, 代理访问到 https://localhost:8001
target: 'http://localhost:8001',
// 开启代理:在本地会创建一个虚拟服务端,然后发送请求的数据,
// 并同时接收请求的数据,这样服务端和服务端进行数据的交互就不会有跨域问题
changOrigin: true, //开启代理
pathRewrite: {
// 会将 /dev-api 替换为 '',也就是 /dev-api 会移除,
// 如 /dev-api/db.json 代理到 https://localhost:8080/db.json
'^/dev-api': '',
}
}
}
},
lintOnSave: false, // 关闭格式检查
productionSourceMap: false // 打包时不会生成 .map 文件,加快打包速度
}
1.5 配置不同环境 常量值
开发环境请求 Mock.js 获取数据,开发环境请求后台接口获取数据,不同环境请求的URL不一样,所以要为不同环 境匹配不同请求接口URL,通过路径前缀进行匹配。当前只针对开发环境,后面会生产部署再讲生产如何实现。
- 在 根目录下创建
.env.development和.env.production文件 - .env.development 文件配置(注意开发和生产环境配置不要搞反了)
# 使用 VUE_APP_ 开头的变量会被 webpack 自动加载
# 定义请求的基础URL, 方便跨域请求时使用
VUE_APP_BASE_API = '/dev-api'
# 接口服务地址, 以你自已的为主
# 可更改为你自已配置的 Easy-Mock 接口服务地址
VUE_APP_SERVICE_URL = 'http://localhost:8080'
- .env.production 文件配置(注意开发和生产环境配置不要搞反了)
# 使用 VUE_APP_ 开头的变量会被 webpack 自动加载
# 定义请求的基础URL, 方便跨域请求时使用
VUE_APP_BASE_API = '/pro-api'
-
测试:在 main.js 中添加以下代码,看下浏览器控制台是否会输出
在项目任意模块文件中,都可以使用 process.env.VUE_APP_BASE_API 获取值
console.log(process.env.VUE_APP_BASE_API)
1.6 重构代理配置
- 在重构 vue.config.js 中的 devServer.proxy 代理配置
module.exports = {
devServer: {
port: 8888, // 端口号,如果端口号被占用,会自动提升1
host: "localhost", //主机名, 127.0.0.1, 真机 0.0.0.0
https: false, //协议
open: true, //启动服务时自动打开浏览器访问
proxy: {
// 匹配 /dev-api 开头的请求,
// '/dev-api': {
[process.env.VUE_APP_BASE_API]: {
// 目标服务器, 代理访问到 https://localhost:8001
// target: 'http://localhost:8001',
target: process.env.VUE_APP_SERVICE_URL,// 在 .env.development 中配置的
// 开启代理:在本地会创建一个虚拟服务端,然后发送请求的数据,
// 并同时接收请求的数据,这样服务端和服务端进行数据的交互就不会有跨域问题
changOrigin: true, //开启代理
pathRewrite: {
// 会将 /dev-api 替换为 '',也就是 /dev-api 会移除,
// 如 /dev-api/db.json 代理到https://localhost:8080/db.json
// '^/dev-api': '',
['^' + process.env.VUE_APP_BASE_API]: ''
}
}
}
},
lintOnSave: false, // 关闭格式检查
productionSourceMap: false // 打包时不会生成 .map 文件,加快打包速度
}
2.修改 utils/request.js 文件配置: baseURL: process.env.VUE_APP_BASE_API
import axios from "axios"
// 手动创建一个 axios 对象, 参考: https://github.com/axios/axios#creating-an-instance
const request = axios.create({
// 请求配置参考: https://github.com/axios/axios#request-config
// 根据不同环境设置 baseURL, 终发送请求时的URL为: baseURL + 发送请求时写URL ,
// 比如 get('/test'), 终发送请求是: /dev-api/test
// baseURL: '/dev-api',
// baseURL: '/',
// 根目录下的 .env.development 与 .env.production 中配置 VUE_APP_BASE_API
baseURL: process.env.VUE_APP_BASE_API, // "/dev-api"
timeout: 5000 // 请求超时
})
export default request // 导出 axios 对象
- 将 test.js 中的 BASE_URL 变成空字符
const BASE_URL = ""
- 重启项目,再次访问