项目背景:uniapp+vue3+ts+vite+pinia+vant
1. 安装axios
npm i axios
2. 封装axios
创建一个名为http.ts的文件
import { ref } from "vue";
import axios from "axios";// 创建一个可以同步访问的 token 变量
export const token = ref(null);// 在需要的地方(如登录成功后),异步获取 token,并将其存储在 token 变量中
uni.getStorage({key: "token"}).then(res => {token.value = res.data;});// 创建 axios 实例
const http = axios.create({baseURL: "http://8.122.18.118:3000", // 这是你的基础 URLtimeout: 5000 // 请求超时时间
});// 请求拦截器
http.interceptors.request.use(config => {// 从 token 变量中获取 tokenif (token.value) {config.headers["Authorization"] = "Bearer " + token.value;}return config;},error => {// 请求错误处理return Promise.reject(error);}
);// 响应拦截器
http.interceptors.response.use(response => {// 如果返回的状态码为 200-299,说明接口请求成功,可以正常拿到数据// 否则的话抛出错误if (response.status >= 200 && response.status < 300) {return Promise.resolve(response);} else {return Promise.reject(response);}},error => {// 响应错误处理return Promise.reject(error);}
);export default http;
3. 跨域代理设置
第二步结束已经可以发送请求了,但是会因为跨域报错
因为我用的vite作为构建工具,Vite有内置的代理功能来解决跨域问题,可以在vite.config.ts 或 vite.config.js 文件中设置代理
// vite.config.ts 或 vite.config.js
export default defineConfig({plugins: [vue()],server: {proxy: {'/api': {target: 'http://8.122.18.118:3000',changeOrigin: true,rewrite: (path) => path.replace(/^\/api/, '')}}}
})
这样的话,任何以 /api 开头的请求都会被代理到 http://8.122.18.118:3000。
然后,需要修改你的 axios 实例(刚刚的http.ts文件),移除 baseURL,或者将其设置为 /api,就像这样:
// 创建 axios 实例
const http = axios.create({baseURL: '/api', // 这是你的基础 URLtimeout: 5000 // 请求超时时间
})
这样,你的请求就会被发送到 http://localhost:3000/api,然后代理服务器会把它转发到 http://8.122.18.118:3000。
4. 在其他页面使用http请求
<script lang="ts" setup>import { ref } from "vue";import http from "@/services/http";// 第一种方式:const testGet = async () => {// 使用http实例发送POST请求const response = await http.post('/some-api-endpoint', {key: 'value'});// 处理响应数据console.log(response.data);};// 第二种方式:const testGet = () => {// 使用http实例发送POST请求http.post('/some-api-endpoint', {key: 'value'}).then(response => {// 处理响应数据console.log(response.data);}).catch(error => {// 处理错误console.error(error);});};
</script>