Axios
简介
Axios,是一个基于promise 的网络请求库,作用于node.js和浏览器中,它是 isomorphic 的(即同一套代码可以运行在浏览器和node.js中)
在服务端它使用原生node.js的http模块, 而在客户端 (浏览端) 则使用XMLHttpRequest
axios它的底层是用了XMLHttpRequest (xhr)方式发送请求和接收响应
xhr相对于Fetch api来说,功能更强大,但由于是比较老的api,不支持Promise
axios对xhr进行了封装,使之支持Promise,并提供了对请求、响应的统一拦截功能
安装
npm install axios -S
创建实例
const _axios = axios.create(config)
获取远程数据
<template>
<div>
<div><input type="button" value="获取远程数据" @click="getRequest"></div>
</div>
</template>
<script>
import axios from 'axios'
const options = {
methods : {
getRequest(){
axios.get('/api/demo')
}
}
};
export default options;
</script>
一般使用两种方法,一种使用promise的then方法来进行异步调用
或者加上async声明异步调用,await等待结果返回(阻塞式)
const options = {
methods : {
async getRequest(){
const response = await axios.get('/api/demo');
console.log(response);
}
}
};
主要请求方法
请求 | 数据 |
---|---|
axios.get(url,[config]) |
限制 |
axios.delete(url,[config]) |
可携带(config中) |
axios.head(url,[config]) |
限制 |
axios.options(url,[config]) |
可携带(config中) |
axios.post(url,[data,config]) |
可携带 |
axios.put(url,[config]) |
可携带 |
axios.patch(url,[data,config]) |
可携带 |
- config 选项对象,例如查询参数,请求头等
- data 请求体数据 json、mutipart…
- get、head请求无法携带请求体,这是浏览器限制所致(xhr,fetch,api均有限制)
- options、delete请求可以通过config中的data携带请求体
携带请求头发送数据
config方法中设置headers,以及请求头的携带数据
//发送请求头的数据
axios.post('/api/demo2',{},
{
headers:{
/*自定义的请求头*/
Authorization:"abc"
}
}
).then(res => {
console.log(res)
});
后端接收
@RequestMapping("/demo2")
public List<Emp> test2(@RequestHeader("Authorization") String authorization){
System.out.println(authorization);
return empService.getEmpList();
}
携带参数发送数据
后端使用参数接值
1、url携带参数
使用el表达式拼接变量值
let name = "os467";
let password = "os4670";
const response = await axios.get(`/api/demo?name=${name}&password=${password}`);
@RequestMapping("/demo")
public List<Emp> test(String name,String password ){
System.out.println("name:"+name);
System.out.println("password:"+password);
return empService.getEmpList();
}
- 特殊符号的处理,例如数据中存在&等特殊含义的符号
encodeURIComponent('&&&')
来对特殊符号进行编码传输
2、config携带参数
async getRequest(){
let name = encodeURIComponent("os467");
let password = "os4670";
//发送请求头的数据
axios.post('/api/demo',{},
{
/*路径字符串参数*/
params:{
name: name,
password: password
}
}
).then(res => {
console.log(res)
});
}
更加推荐使用这种方法传递参数
3、data携带数据
data携带URL参数
此对象会将数据转换为urlencode格式的数据
async getRequest(){
/*需要创建一个路径查询对象*/
let usp = new URLSearchParams();
/*添加key-value*/
usp.append("name","os467");
usp.append("password","os4670");
//发送请求头的数据,第二个data参数传入usp即可
axios.post('/api/demo',
usp
).then(res => {
this.res = res;
});
}
data携带请求体数据
这里我们使用post发起请求来测试
- 一般请求体的数据是在第二个参数data中的,而且默认是Json格式
- 后端需要用@RequestBody注解接收
async getRequest(){
//发送请求头的数据
axios.post('/api/demo3',
{
name:"os467",
password:"os4670"
}
).then(res => {
this.res = res;
});
}
@RequestMapping("/demo3")
public List<Emp> test3(@RequestBody DemoDto demoDto){
System.out.println(demoDto);
return empService.getEmpList();
}
data携带表单数据
或者使用FormData对象封装请求体表单数据
- 后端使用对象或参数接收都可以
async getRequest(){
let params = new FormData();
params.append("name","os467");
params.append("password","os4670");
//发送请求头的数据
axios.post('/api/demo4',
params
).then(res => {
this.res = res;
});
}
@RequestMapping("/demo4")
public List<Emp> test4(DemoDto demoDto){
System.out.println(demoDto);
return empService.getEmpList();
}
axios默认设置
const _axios = axios.create({});
const response = await _axios.post("/api/demo4",
{
name:"os467",
password:"os4670"
}
)
this.res = response
- axios 对象可以直接使用,但使用的是默认的设置
- 使用
axios.create()
方法创建axios,可以覆盖默认设置,config详细配置如下
常见的config有:
名称 | 含义 |
---|---|
baseURL | 将自动加在url前面 |
headers | 请求头,类型为简单对象 |
params | 跟在URL后的请求参数,类型为简单对象或者URLSearchParams |
data | 请求体,类型有简单对象,FormData,URLSearchParams,File等 |
withCredentials | 跨域时是否携带Cookie等凭证,默认为false |
responseType | 响应类型,默认为json |
在实际项目中,为了提高性能,我们一般不用代理,使用baseURL可以同一配置发起请求的地址,我们只需要在后端配置类中配置允许跨域的前端服务地址即可
跨域携带cookie
withCredentials为false的时候不会设置服务器设置的sessionid的cookie信息
前端需要配置withCredentials为true
后端加上
@CrossOrigin(allowCredentials = "true")
注解
或者配置类全局配置允许跨域
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:7070")
.allowCredentials(true);
}
}
前端发起请求
async getRequest(){
const _axios = axios.create({
withCredentials:true
});
/*需要等待后端传递sessionid提供下一次请求使用,所以这里阻塞*/
await _axios.post("/api/demo5",{});
_axios.post("/api/demo6",{});
}
后端接收
@RequestMapping("/demo5")
public List<Emp> test5(HttpSession session){
System.out.println(session.getId());
session.setAttribute("user","os467");
return empService.getEmpList();
}
@RequestMapping("/demo6")
public List<Emp> test6(HttpSession session){
System.out.println(session.getId());
Object user = session.getAttribute("user");
System.out.println("user:"+user);
return empService.getEmpList();
}
可以发现两次sessionid都相同,说明请求允许携带cookie,如果服务端不设置会认为这是跨域返回的cookie不会使用
axios响应对象
名称 | 含义 |
---|---|
data | 响应体数据 |
status | 状态码 |
headers | 响应头 |
- 200 表示响应成功
- 400 请求数据不正确
- 401 身份验证没通过
- 403 没有权限
- 404 资源不存在
- 405 不支请求方式
- 500 服务器内部错误
错误状态下获取相应对象
//错误情况获取响应对象
try{
let response = _axios.get("/api/demo7",{});
console.log(response);
}catch (error){
console.log(error.response);
}
axios拦截器
请求拦截器
_axios.interceptors.request.use(
function (config){
return config;
},
function (error){
return Promise.reject(error);
}
)
例如在使用jwt认证方式的时候,每次请求都需要在请求头中设置令牌信息,一般我们就使用请求拦截器来设置
将token设置到请求头中
_axios.interceptors.request.use(
function (config){
config.headers = {
/*假设这就是token*/
Authorization: 'aaa.bbb.ccc'
}
return config;
}
)
响应的异常统一处理
_axios.interceptors.request.use(req => {} error => {})
配置请求拦截器_axios.interceptors.response.use(req => {} error => {})
配置响应拦截器
存入js文件作为组件,下次使用时导入即可使用
import axios from "axios";
const _axios = axios.create({
withCredentials:true
});
/*请求拦截器*/
_axios.interceptors.request.use(
req => {
console.log("请求成功");
return req;
},
async error => {
console.log("请求失败");
return error;
}
);
/*响应拦截器*/
_axios.interceptors.response.use(
res => {
console.log("响应成功");
return res;
},
async error => {
/*不同状态码不同处理*/
if (error.response.status === 400){
console.log('请求参数不正确');
return Promise.resolve(400);
}
if (error.response.status === 404){
console.log('无法找到资源');
return Promise.resolve(404);
}
return Promise.reject(error);
}
);
export default _axios;
导入组件
import _axios from "@/utils/myaxios";
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以邮件至 1300452403@qq.com