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

news2024/11/26 10:49:47

在这里插入图片描述

目录

  • 一、创建request.js文件
  • 二、创建axios实例
  • 三、创建请求、响应拦截器
  • 四、使用 request.js,测试接口:https://api.uomg.com/api/rand.qinghua
    • 1、调取接口代码书写
    • 2、注意(跨域问题)

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' 重写为 ''

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1604372.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

解决程序化刷新EXCEL提示更新外部链接的弹窗问题

解决方法 【信任中心】-> 【消息栏】->勾选如下策略提示 2. 【信任中心】->【外部内容】->启用下面的三项链接 3. 【信任中心】->【宏设置】->启用所有宏

【Python小游戏】植物大战僵尸的实现与源码分享

文章目录 Python版植物大战僵尸环境要求方法源码分享初始化页面&#xff08;部分&#xff09;地图搭建&#xff08;部分&#xff09;定义植物类 &#xff08;部分&#xff09;定义僵尸类&#xff08;部分&#xff09;游戏运行入口 游戏源码获取 Python版植物大战僵尸 已有的植…

MySQL-笔记-06.数据高级查询

目录 6.1 连接查询 6.1.1 交叉连接&#xff08;cross join&#xff09; 6.1.2 内连接&#xff08;inner join&#xff09; 6.1.3 外连接&#xff08;outer join&#xff09; 6.1.3.1 左外连接&#xff08;left [outer] join&#xff09; 6.1.3.2 右外连接&#xff08;rig…

Meta因露骨AI图片陷入困境

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

Postgresql源码(126)TupleStore使用场景与原理分析

相关 《Postgresql源码&#xff08;125&#xff09;游标恢复执行的原理分析》 《Postgresql游标使用介绍&#xff08;cursor&#xff09;》 总结 开源PG中使用tuple store来缓存tuple集&#xff0c;默认使用work_mem空间存放&#xff0c;超过可以落盘。在PL的returns setof场景…

回文链表leecode

回文链表 偶数情况奇数情况 回文链表leecode 偶数情况 public boolean isPalindrome(ListNode head) {if (head null) {return true;}ListNode fast head;ListNode slow head;while (fast ! null && fast.next ! null) {fast fast.next.next;slow slow.next;}//反…

Day43:LeedCode 1049. 最后一块石头的重量 II 494. 目标和 474.一和零

1049. 最后一块石头的重量 II 有一堆石头&#xff0c;用整数数组 stones 表示。其中 stones[i] 表示第 i 块石头的重量。 每一回合&#xff0c;从中选出任意两块石头&#xff0c;然后将它们一起粉碎。假设石头的重量分别为 x 和 y&#xff0c;且 x < y。那么粉碎的可能结果…

Excel文件解析(Java)

一、概述 在应用程序的开发过程中&#xff0c;经常需要使用 Excel文件来进行数据的导入或导出。所以&#xff0c;在通过Java语言实现此类需求的时候&#xff0c;往往会面临着Excel文件的解析(导入&#xff09;或生成&#xff08;导出)。 在Java技术生态圈中&#xff0c…

Java实现RSA加密示例代码

系列文章目录 文章目录 系列文章目录前言 前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff0c;这篇文章男女通用&#xff0c;看懂了就去分享给你的码吧。 RSA加密是一种非对…

如何配置Postgres的自动扩展功能以应对数据增长

文章目录 解决方案1. 表空间管理2. 分区表3. 自动扩展配置4. 监控和告警5. 使用外部工具和服务 示例代码示例1&#xff1a;创建表空间示例2&#xff1a;创建分区表示例3&#xff1a;调整配置参数示例4&#xff1a;使用监控和告警工具 总结 在PostgreSQL中&#xff0c;随着数据的…

QT-编译报库错误(LF/CRLF)

QT-安装后环境问题记录 版本和环境问题 版本和环境 QT5.15.2 Windows10 QT Creator 问题 在QT夸端开发的项目中 &#xff0c;使用QTCreator打开项目pro文件&#xff0c;编译报出很多系统库 及本地文件中的一些问题&#xff0c;具体如图&#xff1a; 后续&#xff0c;我以为…

宠物店小程序如何搭建制作?宠物店小程序核心功能有哪些?

随着宠物经济的兴起&#xff0c;宠物店的线上服务需求日益增长。微信小程序作为一种便捷的线上服务平台&#xff0c;为宠物店提供了一个与爱宠人士建立联系的新渠道。面对市场上众多的小程序开发选项&#xff0c;宠物店应该如何选择或制作一款适合自己的小程序呢&#xff1f;本…

Java高阶私房菜:快速学会异步编程CompletableFuture

为了使主程代码不受阻塞之苦&#xff0c;一般使用异步编程&#xff0c;而异步编程架构在JDK1.5便已有了雏形&#xff0c;主要通过Future和Callable实现&#xff0c;但其操作方法十分繁琐&#xff0c;想要异步获取结果,通常要以轮询的方式去获取结果&#xff0c;具体如下&#x…

登录github突然出现Two-factor authentication怎么办?

起因 今天想登录github下载项目&#xff0c;输入用户名密码认证之后竟然弹出来了Two-factor authentication&#xff0c;像下图&#xff0c;我只记得之前好像开启过这玩意&#xff0c;但是不知道哪里找这个code了。 解决 在你的iphone里面搜索密码。然后找到github网页&…

程序员能做什么副业?增收致富就靠它们了

作为一个程序员&#xff0c;大家都习惯了朝九晚六&#xff0c;时不时加班的生活。虽然工资听起来比其他行业高一些&#xff0c;但是&#xff0c;都是靠命拼出来的。如何摆脱这种枯燥乏味且前途未卜的生活&#xff0c;应该是很多程序员都在考虑的事情。 而作为一个做了十几年的…

【微服务-Ribbon】什么是负载均衡?微服务中负载均衡有哪些策略呢?

前面几篇文章&#xff0c;我们了解了一下Nacos的单机部署、集群部署以及微服务接入Nacos的步骤。从本篇开始&#xff0c;我们来看一下微服务第二个通用组件-负载均衡&#xff08;Ribbon&#xff09;。 1、Ribbon负载均衡器 负载均衡顾名思义&#xff0c;是指通过软件或者硬件…

javaWeb智能医疗管理系统

简介 在当今快节奏的生活中&#xff0c;智能医疗系统的崛起为医疗行业带来了一场革命性的变革。基于JavaWeb技术开发的智能医疗管理系统&#xff0c;不仅为医疗机构提供了高效、精准的管理工具&#xff0c;也为患者提供了更便捷、更个性化的医疗服务。本文将介绍一个基于SSM&a…

LInux shell编程之基础语法

目录 1、shell概述 1.1、查看Linux 提供的 Shell 解析器 1.2、bash 和 sh 的关系 1.3、查看系统&#xff08;centos&#xff09;默认使用的解释器 2、脚本的基础使用 2.1、脚本的格式 2.2、脚本的执行方式 方式一&#xff1a;采用 bash / sh 脚本的相对路径或绝对路径…

【LeetCode刷题记录】160. 相交链表

160 相交链表 给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点&#xff0c;返回 null 。 图示两个链表在节点 c1 开始相交&#xff1a; 题目数据 保证 整个链式结构中不存在环。 注意&#xff0c;函…

沂水六景记 ——齐源堂主王志强撰文

沂水六景记 ——齐源堂主王志强 明清时期&#xff0c;非常流行“八景”。所谓“八景”&#xff0c;就是在本地众多的风景名胜之中&#xff0c;选定八个最有代表性的美景&#xff0c;分别取上悦耳动听的名字&#xff0c;然后分别题诗。这种给风景选美的做法&#xff0c;是文人…