Axios快速上手

目录

[1 Axios简介](#1 Axios简介)

[2 Axios安装](#2 Axios安装)

[3 Axios简单使用](#3 Axios简单使用)

[4 Axios进阶使用](#4 Axios进阶使用)

[4.1 全局统一配置](#4.1 全局统一配置)

[4.2 导出axios实例](#4.2 导出axios实例)

[4.3 拦截器](#4.3 拦截器)

[4.3.1 请求拦截器](#4.3.1 请求拦截器)

[4.3.2 响应拦截器](#4.3.2 响应拦截器)

[5 Axios项目使用](#5 Axios项目使用)

[5.1 跨域问题](#5.1 跨域问题)

[5.1.1 同源策略与跨域问题](#5.1.1 同源策略与跨域问题)

[5.1.2 跨域问题解决方案](#5.1.2 跨域问题解决方案)

[5.2 代理服务器](#5.2 代理服务器)

[5.2.1 三种常见场景的跨域问题](#5.2.1 三种常见场景的跨域问题)

[5.2.2 代理服务器配置](#5.2.2 代理服务器配置)

[5.3 封装使用流程](#5.3 封装使用流程)

[5.3.1 axios实例封装](#5.3.1 axios实例封装)

[5.3.2 代理服务器封装](#5.3.2 代理服务器封装)

[5.3.3 请求接口方法封装](#5.3.3 请求接口方法封装)


1 Axios简介

Axios是一个基于promise( Promise是JavaScript的异步编程的对象,用来接收异步操作成功或失败以及数据的对象)的网络请求库,可用于node.js和浏览器中。用于node.js就是后端开发发送http请求,用于浏览器就是前端开发发送ajax请求。

Aaxios(ajax i/o system)本质上也是对原生XHR(XMLHttpReques)的封装,只不过它是基于promise的,是promise的实现版本,符合最新的ES规范。

Axios作为请求库,具有如下优势:

  • 标准化:统一浏览器/Node环境请求接口。
  • 拦截器机制:可拦截请求/响应,实现全局逻辑(如Token注入、错误处理)。
  • 自动转换:请求/响应数据自动转为JSON,支持自定义转换逻辑。
  • 取消请求:通过CancelToken中止长时间未响应的请求。

2 Axios安装

终端打开项目地址,输入如下命令:

bash 复制代码
npm install axios  # Node 环境

3 Axios简单使用

要使用Axios,首先需要引入axios包,然后通过create()创建axios实例,才能使用:

javascript 复制代码
import axios from 'axios'
javascript 复制代码
// GET 请求(参数自动拼接到 URL)
axios.get('/user',  { params: { id: 123 } })
  .then(res => console.log(res.data)) 
  .catch(err => console.error(err)); 
 
// POST 请求(自动序列化 JSON)
axios.post('/login',  { username: 'admin', pwd: '123' })
  .then(res => console.log(res)); 

上述通过引入axios,使用get发送GET请求,使用post发送POST请求,通过Promise对象的.then和.catch等链式调用的方式来获取成功态的Promise实例和拒绝态的Promise实例(失败)。

除了get和post请求,还有其它请求方式:

  • get:获取数据
  • post:提交数据(表单提交与文件上传)
  • patch:更新数据(只将修改的数据推送到后端(服务端))
  • put:更新数据(所有数据推送到服务端)
  • delete:删除数据

4 Axios进阶使用

上述使用方式特点是功能简单,并且只能在单个组件中使用,如果要全局使用,就可以创建Axios实例并导出,灵活配置后端URL:

4.1 全局统一配置

全局统一配置Axios实例一般需要单独创建js文件,在其中创建Axios实例并导出:

javascript 复制代码
// 创建 axios 实例
const instance = axios.create({
  //后端服务器ip地址
  baseURL: import.meta.env.VITE_APP_BASE_API,
  timeout: 600000
})

baseURL参数是后端服务器的ip地址,timeout是超时时间。

建议:后端服务器ip地址不要写死,根据环境变量或常量进行灵活动态变化。

4.2 导出axios实例

通过export导出默认的axios实例,接收5个参数:

javascript 复制代码
// 导出自定义请求函数(url是接口地址(因为基本ip地址已经封装,只需接口地址再拼接即可)、请求类型、数据、参数、请求头)
export default ({ url, method, data, params, header }) => {
  return instance({
    url,
    method,
    data,
    params,
    header
  })
}

要使用axios实例的组件需要导入该实例,并传入url(接口地址)、method(请求方法)、data(发送的数据)、params(请求参数)、header(请求头),即可发送请求。

接口地址会被自动拼接到后端服务器ip后从而发送完整的请求路径。

4.3 拦截器

可以在创建axios实例后,对实例添加拦截器,然后在请求发送前和响应接收前做一些特殊处理(公共处理:每个接口都需要进行步骤,比如用户鉴权Token)。

4.3.1 请求拦截器

请求拦截器在请求发送前进行拦截请求,并处理一些事情,比如请求头添加Token:

javascript 复制代码
// 添加请求拦截器
instance.interceptors.request.use(
  (config) => {
    // config就是和此次请求相关的信息,包含请求地址,方法,参数,头等
    const userStore = useUserStore()
    const { token } = userStore
    // 如果有Token,说明已经登录过,所有的登录后请求头应该添加Token
    if (token) {
      config.headers.Authorization = token
    }
    // 必须返回config,否则无法获取响应数据
    return config
  },
  (error) => {
    // 对请求错误做些什么
    return Promise.reject(error)
  }
)

4.3.2 响应拦截器

响应拦截器是在响应被处理前进行拦截,可以对响应数据进行状态码验证、数据解构等操作:

javascript 复制代码
// 添加响应拦截器
instance.interceptors.response.use(
  (response) => {
    // 解构:从响应response对象的data属性才能拿到后端返回的数据
    const { code, data, msg } = response.data
    if (code !== 200000) {
      // 返回一个失败态的 Promise 实例
      // 拦截器后的接口请求方就会收到错误的Promise实例,即被.catch到
      return Promise.reject(new Error(msg))
    }
    // 否则返回纯粹的 data 数据
    return data
  },
  (error) => {
    // 所有的接口响应失败都必须先执行这里
    const { response, status } = error
    //比如http状态是401
    if (status === 401) {
        // token 过期
        // TODO相应的一些关于token删除的操作
        // 返回拒绝态的Promise实例
        return Promise.reject(new Error('token过期'))
    } else {
      // 其它失败状态
      const { code, msg } = response.data
      // 返回失败态的Promise实例,并携带错误信息
      return Promise.reject({
        code,
        msg
      })
    }
  }
)

5 Axios项目使用

前端在开发过程中,如果直接使用axios发送请求,大概率出现跨域问题,要了解跨域问题和解决方案,首先就需要了解同源策略:

5.1 跨域问题

5.1.1 同源策略与跨域问题

(1)同源策略

首先声明同源策略是浏览器的行为策略

同源策略:同源是指浏览器 发出的请求所访问的服务器的url协议一样、域名一样、端口号一样,三者都一样则称为同源。

(2)跨域问题

跨域问题:同源的三个条件只要有一个不一样就是跨域,这是浏览器禁止的行为,浏览器出于安全考虑,采用同源策略,不允许跨域请求。

理解跨域问题的核心是理解浏览器发送请求的行为流程 :这里的浏览器的同源策略是对前端JS代码的约束浏览器通过地址栏输入URL访问前端静态资源是允许的 。而浏览器获取从前端服务器获取到的静态资源中,JS部分访问后端服务器(不同源,和浏览器访问前端资源的URL至少端口号或域名不一样),因此才会发生跨域问题。

比如:浏览器请求前端服务器路径http://localhost:5173,前端服务器的js代码请求后端服务器路径http://localhost:8080,两者端口号不同,因此不满足同源策略。当然这种情况是前端服务器和后端服务器都部署在一台主机上,使用端口号不同。

5.1.2 跨域问题解决方案

(1)CORS:后端开启跨域资源共享,前端不需要做什么事。

(2)请求代理:浏览器访问本地服务器(这也不涉及跨域,因为这是浏览器地址栏URL的基础导航功能,并且自己访问自己凭什么不可以),由本地服务器访问后端服务器,服务器之间不存在跨域问题(因为请求链不涉及浏览器)。

5.2 代理服务器

5.2.1 三种常见场景的跨域问题

传统前后端还未完全分离的项目中,静态资源存储在后端服务器中,浏览器从后端服务器获取静态资源,静态资源中JS代码部分请求后端服务器,因此浏览器请求的URL和后端服务器URL是同源的(同协议、同域名、同端口),只是数据接口的路由地址不同,因此不存在跨域问题。

前后端分离项目,如果未配置跨域请求代理,前端静态资源部署在前端服务器中(Node服务器),浏览器请求前端静态资源,请求的URL是前端服务器的URL,而静态资源的JS部分请求的是后端服务器URL,如果前端服务器和后端服务器在同一个主机上,由于至少端口号不同,因此不同源,即发生跨域问题;如果前端服务器和后端服务器不在同一台主机上,那至少域名不相同(ip),因此也会发生跨域问题。

如果配置跨域请求代理,代理服务器也是前端服务器(仅需添加配置项),因此浏览器请求前端服务器获取静态资源,JS部分请求跨域请求代理,由跨域请求代理转发请求(服务器之间访问不存在浏览器同源策略的限制),此时就不会发生跨域问题。

5.2.2 代理服务器配置

javascript 复制代码
export default defineConfig({
  // 开发服务器配置
  server: {
    port: 80, // 端口
    open: true, // 自动打开浏览器
    // 配置跨域请求代理
    proxy: {
      '/dev-api': {
        // 目前服务器地址(目前开发阶段暂时用本地ip+端口号模拟,实际应该用后端服务器的ip地址+端口号)
        target: 'http://127.0.0.1:18081',
        changeOrigin: true, // 改变请求头的origin源,保证到达后端服务器的值是target值而不是前端请求路径
        // 路径重写:不进行重写,请求到达后端就是:服务器地址+/dev-api+请求的接口地址
        // 如果后端服务器的接口地址没有/dev-api,就会请求不到资源,因此需要替换为空字符串
        rewrite: (path) => path.replace(/^\/dev-api/, '')
      }
    }
  }
})

在vite.config.js中配置Node服务器server,port是前端服务器的端口,open是启动项目自动打开首页策略。

proxy是跨域请求代理的配置项,配置转发路由为/dev-api,target是后端服务器地址,changeOrigin为true表示改变请求头的origin源,确保后端接收的请求的目标URL是后端服务器的值而不是前端发出的值。rewrite表示对路径进行重写,去除/dev-api路由。

即完整的流程如下:

(1)前端服务器位于http://localhost:80浏览器请求静态资源的URL为http:localhost:80/example/api(前端服务器地址+JS请求后端的接口路由)。

(2)JS部分的Axios在请求路径添加http:localhost:80/dev-api/example/api发送到代理服务器(Node服务器监听80端口,如果请求路径是/dev-api,则由代理服务器处理该URL)。

(3)后端服务器位于http://localhost:18081,**代理服务器重写请求URL为http://localhost:18081/example/api并转发该请求**,因此解决跨域请求问题。

5.3 封装使用流程

由于Axios的使用流程比较固定,且每个前端涉及到请求后端的项目中都需要上述配置,因此可以对这部分进行封装,所有的项目都可以按照统一流程处理和使用:

5.3.1 axios实例封装

创建js文件,配置如下内容:

(1)导入Axios并创建实例:即全局统一配置部分;

(2)配置实例的拦截器;

(3)导出Axios实例。

5.3.2 代理服务器封装

即5.2.2代理服务器配置部分,在vite.config.js文件添加。

5.3.3 请求接口方法封装

创建api包,内部放js文件,文件内容是发送请求的方法。比如登录请求:

javascript 复制代码
export const loginApi = ({ phone, password }) => {
  return request({
    method: 'post',
    url: '/admin/sys_user/login/password',
    data: {
      phone,
      password
    }
  })
}

使用该方法就在对应的组件中导入该方法,传入参数即可发送请求。

相关推荐
醒了接着睡6 小时前
Vue3 响应式中的 Reactive
vue.js
paopaokaka_luck7 小时前
基于SpringBoot+Vue的志行交通法规在线模拟考试(AI问答、WebSocket即时通讯、Echarts图形化分析、随机测评)
vue.js·人工智能·spring boot·后端·websocket·echarts
程序定小飞7 小时前
基于springboot的蜗牛兼职网的设计与实现
java·数据库·vue.js·spring boot·后端·spring
我的写法有点潮10 小时前
彻底理解 JavaScript 的深浅拷贝
前端·javascript·vue.js
柯南二号11 小时前
【大前端】Vue 和 React 的区别详解 —— 两大前端框架深度对比
前端·vue.js·前端框架
weixin_4469388712 小时前
uniapp vue-i18n如何使用
前端·vue.js·uni-app
csgo打的菜又爱玩16 小时前
Vue 基础(实战模板与命名指南)
前端·javascript·vue.js
gerrgwg19 小时前
Vue-library-start,一个基于Vite的vue组件库开发模板
前端·javascript·vue.js
星晨雪海1 天前
怎么格式化idea中的vue文件
前端·vue.js·intellij-idea