axios

前言

使用 vue 开发时,频繁使用到了 axios 这个网络请求库,这里对其做一个发起请求时携带参数方式的小结。

一、基本使用

1.1. GET 请求

注意:GET 请求无请求体,可以是可以有请求体 body 的,但是不建议带。

为什么不建议带请求体?

:::details 由文心大模型 3.5 生成

在 HTTP 协议中,GET 请求通常用于请求数据,而 POST 请求则通常用于提交数据。这是因为 GET 和 POST 请求在语义和使用上有一些不同:

  1. 语义上的不同 :
    • GET 请求:通常用于请求数据,它的语义是"获取"或"查询"。浏览器会把 GET 请求的结果(响应体)直接展示给用户。
    • POST 请求:通常用于提交数据,它的语义是"提交"或"更新"。POST 请求的结果通常是一个操作的结果,而不是直接展示给用户的数据。
  2. 请求体的处理 :
    • GET 请求:虽然 GET 请求可以包含请求体(body),但大多数 HTTP 客户端和服务器在处理 GET 请求时都会忽略请求体。这是因为 GET 请求的设计初衷就是为了从服务器获取数据,而不是提交数据。GET 请求的查询参数应该放在 URL 的查询字符串中,而不是请求体中。
    • POST 请求:POST 请求通常包含请求体,用于提交数据给服务器。服务器会处理 POST 请求的请求体来获取提交的数据。
  3. 缓存和书签 :
    • GET 请求是幂等的和安全的,这意味着多次执行相同的 GET 请求应该得到相同的结果,并且不会改变服务器上的任何数据。因此,浏览器通常会对 GET 请求进行缓存。如果 GET 请求包含请求体,这可能会导致缓存行为不一致或不可预测。
    • 由于 GET 请求的 URL 通常会被浏览器记录在历史记录或书签中,如果 URL 中包含了敏感信息(这些信息通常应该放在请求体中),那么这些信息可能会被泄露。
  4. URL 长度限制 :
    • 浏览器和服务器通常对 URL 的长度有一定的限制。如果 GET 请求包含大量的数据在 URL 中(通过查询参数),这可能会导致 URL 超过长度限制。
  5. 安全性 :
    • 将敏感信息(如密码、私钥等)放在 GET 请求的 URL 中是不安全的,因为这些信息可能会被记录在浏览器历史、服务器日志或代理缓存中。这些信息应该通过 POST 请求放在请求体中,并使用适当的加密和身份验证机制来保护。

综上所述,虽然技术上 GET 请求可以包含请求体,但出于上述原因,通常不建议在 GET 请求中包含请求体。在实际开发中,应该根据请求的性质和目的选择合适的 HTTP 方法,并遵循相应的最佳实践。

:::


1.1.1. 使用 GET 方式进行无参请求

接口

Java 复制代码
 @GetMapping("/get/getAll")
 public ResResult getAllUser(){
	 List<User> list = userService.list();
	 return ResResult.okResult(list);
 }

请求

JavaScript 复制代码
 axios({
	 url:'http://localhost:8080/get/getAll',
	 method:'get'
 }).then(res=>{
	 console.log(res.data.data)
 })
1.1.2. 使用 GET 方式请求,参数值直接放在路径中

接口

Java 复制代码
 @GetMapping("/get/{id}")
 public ResResult getUserById(@PathVariable("id") Long id){
         User user = userService.getById(id);
         return ResResult.okResult(user);
 }

请求

JavaScript 复制代码
 axios({
	 url:'http://localhost:8080/get/1',
	 method:'get'
 }).then(res=>{
	 console.log(res.data.data)
 })
1.1.3. 使用 GET 方式请求,参数拼接在路径中

拼接方式 ①

使用 ? 进行参数拼接

接口

Java 复制代码
 @GetMapping("/get")
     public ResResult getUserByIds(@RequestParam("id") Long id){
         User user = userService.getById(id);
         return ResResult.okResult(user);
 }

请求

JavaScript 复制代码
 axios({
	 url:'http://localhost:8080/get?id=1',
	 method:'get'
 }).then(res=>{
	 console.log(res.data.data)
 })

拼接方式 ②

使用 params 【单个参数】

接口

Java 复制代码
@GetMapping("/get")
    public ResResult getUserByIds(@RequestParam("id") Long id){
        User user = userService.getById(id);
        return ResResult.okResult(user);
}

请求

JavaScript 复制代码
 axios({
	 url:'http://localhost:8080/get',
	 params:{
		 id:'2'
	 },
	 method:'get'
 }).then(res=>{
	 console.log(res.data.data)
 })

拼接方式 ③

使用 params 【多个参数】

接口

Java 复制代码
@GetMapping("/get")
    public ResResult getUserByIds(@RequestParam("id") Long id,@RequestParam("username") String username){
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getUsername,username);
        wrapper.eq(User::getId,id);
        User user = userService.getOne(wrapper);
        return ResResult.okResult(user);
 }

请求

JavaScript 复制代码
axios({
	url:'http://localhost:8080/get',
	params:{
		id:'2',
		username:'swx'
	},
	method:'get'
}).then(res=>{
	console.log(res.data.data)
})

当 POST 有参请求且是简写时,要以 JSON 格式请求

JavaScript 复制代码
axios.post('http://localhost:8080/post',"id=2&username=swx").then(res=>{
	console.log(res.data.data)
}).catch(err=>{
	console.log('timeout')
	console.log(err)
})
1.1.4. GET 请求的简写方式

无参时:

JavaScript 复制代码
axios.get('http://localhost:8080/get/getAll').then(res=>{
	console.log(res.data.data)
}).catch(err=>{
	console.log('timeout')
	console.log(err)
})

有参时:

JavaScript 复制代码
axios.get('http://localhost:8080/get',{params:{id:'2',username:'swx'}}).then(res=>{
	console.log(res.data.data)
}).catch(err=>{
	console.log('timeout')
	console.log(err)
})

1.2. POST 请求

注意:POST 请求的有参、无参请求与如上的 GET 是一样的,只不过是请求方式名换一下。

如下是 POST 请求简写与传入配置项写法时,关于请求体格式的一点区别:

接口

JavaScript 复制代码
var express = require('express')
var path = require('path')
var bodyParser = require('body-parser')
const { json } = require('body-parser')
var app = express()


app.use(express.static(path.join(__dirname, 'public')))

app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())


app.get('/a', function(req, res) {
    console.log(req.query)
    res.send({ "id": 1, "name": "张三" })
})



app.listen(3000, function() {
    console.log('app is runing...')
})

请求

写法 ①

如果使用 Axios 的 POST 请求的简写形式,需要将数据以 JSON 格式传递。

JavaScript 复制代码
axios.post('/a', {
	"id": 5,
	"name": "ssss"
}).then(response => {
	console.log('/a1', response.data)
}, error => {
	console.log('错误', error.message)
})

请求

写法 ②

如果将数据直接作为请求体传递,不需要将数据写成 JSON 格式。axios 会根据请求头的 Content-Type 自动处理数据格式。

JavaScript 复制代码
axios({
		method: 'POST',
		url: '/a',
		data: {
			id: 1,
			name: "张三"
		}
	})
	.then(response => {
		console.log('/a', response.data)
		return response.data
	}, error => {
		console.log('错误', error.message)
	})

二、请求失败处理

JavaScript 复制代码
axios.get('http://localhost:8080/get',{params:{id:'2',username:'swx'}}).then(res=>{
	console.log(res.data.data)
}).catch(err=>{
	console.log('timeout')
	console.log(err)
})

三、axios 并发请求

方式 1

接口

Java 复制代码
@GetMapping("/get/getAll")
    public ResResult getAllUser(){
        List<User> list = userService.list();
        return ResResult.okResult(list);
    }

@GetMapping("/get/get")
    public ResResult getUserByIdt(@RequestParam("id") Long id){
        User user = userService.getById(id);
        return ResResult.okResult(user);
    }

请求

JavaScript 复制代码
axios.all([
	axios.get('http://localhost:8080/get/getAll'),
	axios.get('http://localhost:8080/get/get',{params:{id:'1'}})
]).then(res=>{
	//返回的是数组,请求成功返回的数组
	console.log(res[0].data.data),
	console.log(res[1].data.data)
}).catch(err=>{
	console.log(err)
})

方式 2:使用 spread 方法处理返回的数组

html 复制代码
<script>
  axios
    .all([
      axios.get("http://localhost:8080/get/getAll"),
      axios.get("http://localhost:8080/get/get", { params: { id: "1" } }),
    ])
    .then(
      axios.spread((res1, res2) => {
        console.log(res1.data.data), console.log(res2.data.data);
      })
    )
    .catch((err) => {
      console.log(err);
    });
</script>

四、axios 全局配置

JavaScript 复制代码
axios.defaults.baseURL='http://localhost:8080'; //全局配置属性
axios.defaults.timeout=5000; //设置超时时间

//发送请求
axios.get('get/getAll').then(res=>{
	console.log(res.data.data)
});

axios.post('post/getAll').then(res=>{
	console.log(res.data.data)
});

五、axios 实例

JavaScript 复制代码
//创建实例
let request = axios.create({
	baseURL:'http://localhost:8080',
	timeout:5000
});
//使用实例
request({
	url:'get/getAll'
}).then(res=>{
	console.log(res.data.data)
});

request({
	url:'post/getAll',
	method:'post'
}).then(res=>{
	console.log(res.data.data)
})

六、axios 拦截器

axios 提供了两大类拦截器:

  • 一种是请求方向的拦截(成功的、失败的)
  • 一种是响应方向的拦截(成功的,失败的)

拦截器作用:

比如:请求之前在请求头加 token、强制登录

响应的时候可以进行相应的数据处理

请求拦截器

JavaScript 复制代码
    //创建实例
    let request = axios.create({
        baseURL:'http://localhost:8080',
        timeout:5000
    });

    //配置axios拦截器
    request.interceptors.request.use(config=>{
        console.log("请求进来了...")
        console.log("请求成功方向")
        console.log(config.data.data)
        //放行请求,这一步很重要,否则报错
        return config;
    },err=>{
        console.log("请求进来了...")
        console.log("请求失败方向")
        console.log(err)
    });

    //如果没有创建实例,则使用以下方式
    //配置axios拦截器
    // axios.interceptors.request.use(config=>{
    //     console.log("请求进来了...")
    //     console.log("请求成功方向")
    //     console.log(config)
    //     //放行请求
    //     return config;
    // },err=>{
    //     console.log("请求进来了...")
    //     console.log("请求失败方向")
    //     console.log(err)
    // });

    //使用实例
    request({
        url:'get/getAll'
    }).then(res=>{
        console.log(res.data.data)
    });

响应拦截器

JavaScript 复制代码
    //创建实例
    let request = axios.create({
        baseURL:'http://localhost:8080',
        timeout:5000
    });

    //配置axios拦截器
    request.interceptors.response.use(config=>{
        console.log("响应进来了...")
        console.log("响应成功方向")
        console.log(config.data.data)
        //放行响应
        return config;
    },err=>{
        console.log("响应进来了...")
        console.log("响应失败方向")
        console.log(err)
    });

    //使用实例
    request({
        url:'get/getAll'
    }).then(res=>{
        console.log(res.data.data)
    });

七、vue 中封装 axios

封装在 request.js 中

JavaScript 复制代码
//导入axios
import axios from 'axios'

//创建axios实例
const service = axios.create({
  baseURL: 接口地址,
  timeout: 5000
})


//请求拦截器
service.interceptors.request.use(
  config => {

    if (store.getters.token) {
      config.headers['token'] = getToken()
    }
    //放行请求
    return config
  },
  error => {
    console.log(error)
    return Promise.reject(error)
  }
)


//响应拦截器
service.interceptors.response.use(
  response => {
	//返回的数据
    const res = response.data

    if (res.code !== 200) {
      Message({
        message: res.message || 'Error',
        type: 'error',
        duration: 5 * 1000
      })

      // 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired;
      if (res.code === 50008 || res.code === 50012 || res.code === 50014) {
        // to re-login
        MessageBox.confirm('You have been logged out, you can cancel to stay on this page, or log in again', 'Confirm logout', {
          confirmButtonText: 'Re-Login',
          cancelButtonText: 'Cancel',
          type: 'warning'
        }).then(() => {
          store.dispatch('user/resetToken').then(() => {
            location.reload()
          })
        })
      }
      return Promise.reject(new Error(res.message || 'Error'))
    } else {
      return res
    }
  },
  error => {
    console.log('err' + error) // for debug
    Message({
      message: error.message,
      type: 'error',
      duration: 5 * 1000
    })
    return Promise.reject(error)
  }
)

export default service

哪个模块需要发送请求直接引入即可,将以上实例导入

比如:此模块的所有请求接口:api 下的 skuInfo.js

JavaScript 复制代码
//导入axios实例
const api_name = '/admin/product/skuInfo'

export default {

  getPageList(page, limit, searchObj) {
    return request({
      url: `${api_name}/${page}/${limit}`,
      method: 'get',
      params: searchObj
    })
  },

  save(role) {
    return request({
      url: `${api_name}/save`,
      method: 'post',
      data: role
    })
  },

  //新人专享
  isNewPerson(id, status) {
    return request({
      url: `${api_name}/isNewPerson/${id}/${status}`,
      method: 'get'
    })
  },
}

list.vue 页面中使用

JavaScript 复制代码
 //先导入
 import api from '@/api/product/skuInfo'
 ​
 api.getPageList(this.page, this.limit, this.searchObj).then(
         response => {
           debugger
           this.list = response.data.records
           this.total = response.data.total
 ​
           // 数据加载并绑定成功
           this.listLoading = false
         }
       )
     }
 ​
 api.save(this.skuInfo).then(response => {
         if (response.code) {
           this.$message({
             type: 'success',
             message: response.message
           })
           this.$router.push({ path: '/product/skuInfo/list' })
           this.saveBtnDisabled = false
         }
       })
 ​
 //新人专享
 handleNewPersonChange(index, row) {
       api.isNewPerson(row.id, row.isNewPerson).then(response => {
         this.$message({
           type: 'info',
           message: '操作成功'
         })
         this.fetchData()
       })
     }
   }

main.js 中引入使用

JavaScript 复制代码
 import * as API from '@/api'
 ​
 Vue.prototype.$API = API
相关推荐
定栓3 小时前
Webpack迁到Vite第一节:模块系统迁移:require → import
运维·前端·webpack
小熊在忙fpga3 小时前
N32G430芯片的flash表示
前端·javascript·html
Data analyse4563 小时前
App埋点版本兼容的字段迁移校验
大数据·运维·服务器·前端·数据库·数据分析
todoitbo4 小时前
本来只想给内网开个口子,Natapp 却多给了一道防护
前端·javascript·vue.js·内网穿透·网络防护·natapp
会灭火的程序员4 小时前
SuperMap AgentX Server智能体接入WEB应用技术文档
前端·supermap·agentx·agentx server
CRMEB4 小时前
商品 SKU 设计,从简单规格到多规格踩过什么
java·前端·数据库·开源
Chloe.Zz4 小时前
一篇入门Agent
开发语言·前端·javascript
java1234_小锋4 小时前
【技术专题】HTML5 网页技术 - HTML5 表格标签
前端·html·html5
雪芽蓝域zzs4 小时前
JS 项目转 TS 项目(Vue3 + 若依这类后台项目)完整改造清单
前端·vue.js