使用vite从头搭建一个vue3项目(四)使用axios封装request.js文件,并使用proxy解决跨域问题

7 篇文章 0 订阅

在这里插入图片描述

axios 的二次封装有三个要点:

  • 创建 axios 实例,axios.create()
  • 创建请求拦截器,interceptors.request.use()
  • 创建响应拦截器,interceptors.response.use()

一、创建request.js文件

安装 axios 插件,指令: npm i axios

src/utils 目录下创建 request.js 文件,并引入 axios。

import axios from "axios"

二、创建axios实例

import axios from "axios"

console.log(import.meta);
// 创建axios实例
const instance = axios.create({
  baseURL: import.meta.env.VITE_BASE_API,  // 设置默认的 API 地址
  timeout: 5000,						   // 设置请求超时时间
  headers: { 'systemType': 'IOS' }         // 设置请求header,可以自定义属性
})

export default instance;

import.meta 是个什么东西?

import.meta 是一个 ES 模块(ESM)特性,它提供了有关当前模块的元数据。在 Vue 3 中,import.meta 可以用于访问当前 Vue 应用程序实例的上下文信息,如应用程序的基本 URL、环境变量等。

在这里插入图片描述

Vite 官网也说过:Vite 在一个特殊的 import.meta.env 对象上暴露环境变量。
在这里插入图片描述

三、创建请求、响应拦截器

src/utils 中创建 token 操作文件 auth.js。

const tokenKey = 'vite_token'; // 自定义tokenKey
// 获取token
export function getToken() {
  return sessionStorage.getItem(tokenKey);
}
// 设置token
export function setToken(token) {
  return sessionStorage.setItem(tokenKey, token);
}
// 删除token
export function removeToken() {
  return sessionStorage.clear();
}

拦截器代码逻辑(完整代码):

import axios from "axios"
import { getToken } from "./auth";
import { ElMessage } from 'element-plus';

console.log(import.meta);
// 创建axios实例
const instance = axios.create({
  baseURL: import.meta.env.VITE_BASE_API, // 设置默认的 API 地址,url = baseURL + url(使用proxy代理时此处可不写)
  timeout: 5000,						  // 设置请求超时时间
  headers: { 'systemType': 'IOS' }        // 设置请求header,可以自定义属性
})

// 请求拦截器
instance.interceptors.request.use(
  // 请求配置(全局),一般在登录时后端返回token,此处设置token后,前端每次调取接口都会携带token
  (config) => {
    const token = getToken();
    if (token) {
      config.headers.token = token;
    }
    return config;
  },
  // 请求错误
  (error) => {
    return Promise.reject(error)
  }
)
// 响应拦截器
instance.interceptors.response.use(
  // 响应数据,2xx 范围内的状态码都会触发该函数。
  (response) => {
    const { status, data } = response;
    if (status === 200) {
      const { code, message } = data;
      // 根据后端返回的自定义状态码 code 进行错误信息提示(根据具体需求确定是否需要书写)
      switch (code) {
        case 1001:
          ElMessage({ message: '登录信息已过期,请重新登录!', type: 'error' })
          return Promise.reject(data);
        case 1002:
          ElMessage({ message: '当前账号已在其它端登录,请重试!', type: 'error' })
          return Promise.reject(data);
        case 1003:
          ElMessage({ message: message || '未知错误', type: 'error' })
          return Promise.reject(data);
        default:
          return data;
      }
    }
  },
  // 响应错误,超出 2xx 范围的状态码都会触发该函数。
  (error) => {
    if (error.response) {
      // 请求已发送,收到响应,但状态码非 2xx ,根据 http 状态码来判断响应错误信息
      const { status, data } = error.response;
      if (status === 2001) {
        ElMessage({ message: '没查到对应数据!', type: 'error' })
      } else if (status === 2002) {
        ElMessage({ message: '服务器开小差了!', type: 'error' })
      } else {
        ElMessage({ message: data.message || '未知错误!', type: 'error' })
      }
    } else if (error.request) {
      // 请求已发送,未收到响应
      ElMessage({ message: error.message || '请求已发送,未收到响应信息!', type: 'error' })
    } else {
      // 其他错误
      ElMessage({ message: error.message, type: 'error' })
    }
    // 若简写,上面代码可省略,只写此一行
    return Promise.reject(error);
  }
)

export default instance;

四、使用 request.js,测试接口:https://api.uomg.com/api/rand.qinghua

1、调取接口代码书写

src/api/about 目录下创建 index.js 文件,引入request.js,创建一个请求函数。

import request from '@/utils/request';

// 获取随机搞笑语句
export function getMessage(params = {}) {
  return request({
    url: '/api/rand.qinghua',
    method: 'POST',
    data: params
  })
}

src/pages/about/index.vue 组件中使用:

<template>
  <div class="about">
    <h3>This is About page!</h3>
    <el-button type="default" @click="handleClick">切换内容</el-button>
    <h4>{{ message }}</h4>
  </div>
</template>
<script setup>
import { getMessage } from '@/api/about'

const message = ref("")
onMounted(() => {
  handleClick();
})
function handleClick() {
  getMessage().then(res => {
    const { content } = res;
    message.value = content;
  })
}
</script>
<style lang="less" scoped>
.about {
  h3 {
    color: grey;
  }
}
</style>

需要修改 .env.development 文件:

## 开发环境
VITE_MODE='development'

# 变量必须以 VITE_ 为前缀才能暴露给外部读取
VITE_BASE_API = 'https://api.uomg.com/'

因为 about 组件中使用了 Element Plus UI 组件库,所以还得安装一下:npm i element-plus,然后在 main.js 文件中全局引入:

import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import './style.css'
import '@style/index.scss'
import '@style/index.less'

import App from './App.vue'
import router from "@/router"

const app = createApp(App)

app.use(router)
app.use(ElementPlus)
app.mount('#app')

如果想要按需引入 Element Plus 组件,首先你需要安装 unplugin-vue-componentsunplugin-auto-import 这两款插件。详情请参考:https://element-plus.org/zh-CN/guide/quickstart.html

2、注意(跨域问题)

因为测试的 API 地址协议为 https,而本地使用的是 http,所以会出现跨域问题:
在这里插入图片描述

这时候就必须使用代理 proxy了。而要使用 proxy 代理,则 request.js 文件中的 baseURL 配置项就不再需要了。

此处说明一下:

  • 如果 axios 的 baseURL 配置的是绝对路径,例如 'http://192.168.1.32:8000/',axios 会直接发送请求而不经过 server.proxy。
  • 如果 axios 的 baseURL 配置的是相对路径,例如 '/api',则可以正常使用 server.proxy 进行请求转发,不会存在跨域问题

此处若配置 baseURL,则路径地址变成了 https://api.uomg.com/api/rand.qinghua 这样的绝对路径;而不配置 baseURL ,则为相对路径 /api/rand.qinghua。proxy匹配到了 '/api',会使用配置的 target 选项拼接成完整路径:target + '/api/rand.qinghua' 进行请求。

当然,此处的配置还有其他方式,不做赘述。

const instance = axios.create({
  baseURL: '',  // 设置默认的 API 地址,url = baseURL + url
  timeout: 5000,                           // 设置请求超时时间
  headers: { 'systemType': 'IOS' }         // 设置请求header,可以自定义属性
})

vite.config.js 文件中的 proxy 配置也需要修改:

proxy: {
  '/api': {
    target: env.VITE_BASE_API,                      
    changeOrigin: true,                             
    // rewrite: (path) => path.replace(/^\/api/, ''),  // 此行注释
  },
}

因为 '/api' 是地址 https://api.uomg.com/api/rand.qinghua 中的成员,所以 rewrite 配置项不需要再将 '/api' 重写为 ''

看效果:
在这里插入图片描述

  • 23
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,下面是搭建 Vue3 项目的步骤: 1. 安装 Node.js 首先,你需要在你的电脑上安装 Node.js。Node.js一个基于 Chrome V8 引擎的 JavaScript 运行环境。你可以在 https://nodejs.org/ 上下载并安装 Node.js。 2. 安装 Vue CLI Vue CLI 是一个官方的 Vue.js 项目脚手架,可以帮助你快速搭建一个 Vue 项目。你可以使用以下命令安装 Vue CLI: ``` npm install -g @vue/cli ``` 3. 使用 Vue CLI 创建项目 使用 Vue CLI 创建一个新的 Vue 项目非常简单,只需要执行以下命令: ``` vue create your-project-name ``` 在创建项目的过程中,你需要选择一些选项,例如: - 选择一个预设(你可以选择默认的预设或手动配置) - 选择要使用的插件(例如 TypeScript、Vuex、Vue Router、Axios 等) - 配置项目的名称、描述等信息 在这个过程中,你需要选择 TypeScript、Vuex、Vue Router 和 Axios 插件,并选择手动配置预设。在手动配置预设时,你需要选择 Vue 3 和 Babel 编译器。 4. 安装 Element Plus Element Plus 是一个基于 Vue 3 的 UI 组件库,可以帮助你快速构建界面。你可以使用以下命令安装 Element Plus: ``` npm install element-plus --save ``` 然后,在你的 main.ts 文件中引入 Element Plus: ```typescript import { createApp } from 'vue' import App from './App.vue' import router from './router' import store from './store' import ElementPlus from 'element-plus' import 'element-plus/dist/index.css' createApp(App).use(store).use(router).use(ElementPlus).mount('#app') ``` 5. 使用 Sass Sass 是一种 CSS 预处理器,可以帮助你更加方便地书写 CSS。你可以使用以下命令安装 Sass: ``` npm install sass --save-dev ``` 然后,在你的 App.vue 文件使用 Sass: ```vue <template> <div class="app"> <h1>Hello, world!</h1> </div> </template> <style lang="scss"> .app { color: red; } </style> ``` 6. 配置 Axios Axios一个用于发送 HTTP 请求的 JavaScript 库。你可以使用以下命令安装 Axios: ``` npm install axios --save ``` 然后,在你的 main.ts 文件中配置 Axios: ```typescript import axios from 'axios' axios.defaults.baseURL = 'http://localhost:3000/api' axios.defaults.timeout = 5000 axios.interceptors.request.use(config => { // 在发送请求之前做些什么 return config }, error => { // 对请求错误做些什么 return Promise.reject(error) }) axios.interceptors.response.use(response => { // 对响应数据做些什么 return response }, error => { // 对响应错误做些什么 return Promise.reject(error) }) ``` 现在你已经成功搭建一个 Vue3 项目使用了 TypeScript、ViteVuex、Element Plus、Axios、Sass 和 Vue Router。你可以根据你的需要进行进一步的开发。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值