0
点赞
收藏
分享

微信扫一扫

2024年2月个人工作生活总结

_karen 03-01 13:30 阅读 2

7.axios 异步通信

官网 : http://www.axios-js.com/zh-cn

Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。

特性

  • 从浏览器中创建 XMLHttpRequests

  • 从 node.js 创建 http请求

  • 支持 Promise API

  • 拦截请求和响应

  • 转换请求数据和响应数据

  • 取消请求

  • 自动转换 JSON 数据

  • 客户端支持防御 XSRF

7.0.前置技术

7.0.1.AJAX

7.0.1.1.什么是AJAX

AJAX(Asynchronous JavaScript and XML)是一种创建交互式网页应用的Web开发技术,

允许网页在不进行整体刷新的情况下与服务器交换数据并更新部分网页内容。

尽管名称中包含XML,但在实际应用中,JSON由于其更轻量级和易于使用的特性,已经成为了与服务器交换数据时更常见的格式。

AJAX的核心是使用JavaScript与浏览器内置对象 XMLHttpRequest 或者 Fetch API 进行异步通信。

通过这些API,前端JavaScript代码可以在后台发送HTTP请求到服务器,获取数据,

并在请求完成后通过DOM操作来更新页面的部分内容,从而实现用户界面的无缝、动态更新。

AJAX技术的特点包括:

  1. 异步:这意味着当向服务器发送请求时,用户的浏览器不会被阻塞或等待响应完成,而是可以继续执行其他脚本和处理用户交互。

  2. 无刷新更新:仅更新需要改变的数据区域,而不是整个页面,提高了用户体验和应用程序性能。

  3. 减少服务器负载:由于只需要传输必要的数据,而非整个页面内容,因此能有效减少带宽消耗和服务器压力。

  4. 增强交互性:使Web应用能够实时响应用户操作,提供类似桌面应用的流畅体验。

7.0.1.2.XMLHttpRequest
//1. 创建对象
const xhr = new XMLHttpRequest();
//2. 初始化
xhr.open("GET", "...");
//3. 发送
xhr.send();
//4. 绑定事件, 处理响应结果
xhr.onreadystatechange = function () {
    //判断
    if (xhr.readyState === 4) {
        //判断响应状态码 200-299
        if (xhr.status >= 200 && xhr.status < 300) {
            //表示成功
            console.log(xhr.response);
        } else {
            //如果失败
            console.log(xhr.status);
        }
    }
}
7.0.1.3.Controller中的注解

在方法上可以使用 @ResponseBody , 将 转页转变成 返回数据

如果当前 Controller中的全部方法都要使用 @ResponseBody, 可以直接将 @Controller 更换成 @RestController

7.0.2.Promise

7.0.3.RESTful风格

7.0.3.1.通信方式 method

get 查询

post 添加

put/patch 全部数据 /部分数据 更新

delete 删除

7.0.3.2.路径传参 @PathVariable

请求路径传参 : url/value

接值 :

@PostMapping("/url/{param}")
public void test(@PathVariable("param") String param){
    System.out.println("param = " + param);
}
7.0.3.3.接收对象 @RequestBody
@PostMapping("/url")
public void testVo(@RequestBody Vo vo){
    System.out.println("vo = " + vo);
}

7.0.4.跨域

7.0.4.1.概念

跨域(Cross-Origin)是指浏览器的一种安全策略,即同源策略(Same-Origin Policy)。

同源策略限制了一个源(协议+域名+端口)加载的文档或脚本如何与来自另一个源的资源进行交互。这是为了防止恶意网站窃取和篡改其他网站的内容。

当一个请求发起时,如果它的协议、主机名和端口号与当前页面的不完全相同,就被认为是跨域请求。在默认情况下,浏览器会阻止这种跨域请求,以保护用户的隐私和数据安全。

跨域问题在Web开发中尤为常见,尤其是在使用Ajax技术或Fetch API从不同的源获取数据时。为了解决这个问题,有以下几种常见的跨域解决方案:

  1. CORS (Cross-Origin Resource Sharing):一种由服务器支持的机制,服务器可以在HTTP响应头中添加特定的字段,允许指定来源的跨域请求。例如 Access-Control-Allow-Origin 头部用于指定哪些源可以访问资源。

  2. JSONP (JSON with Padding):通过动态创建 <script> 标签并指向一个提供 JSONP 服务的 URL 来绕过同源策略,因为 <script> 标签不受同源策略限制。JSONP 的原理是服务器返回一个JavaScript函数调用,并将数据作为参数传递给该函数。

  3. WebSocketServer-Sent Events (SSE):这两种技术都允许服务器向客户端推送数据,并且它们通常支持跨域配置。

  4. 反向代理:在前端应用服务器上设置反向代理,使得所有对第三方API的请求看起来像是来自于同一个源。

  5. 自定义协议或文件协议:某些场景下,可以通过在本地建立自定义协议或者利用浏览器的 file:// 协议绕过同源策略,但这不是常规的跨域解决方案,只适用于特定环境。

根据实际应用场景选择合适的跨域解决方案来实现不同源之间数据的安全交换。

7.0.4.2. Springboot 解决跨域问题

由于 当前 前后台分离 , 发出的请求会遇到 CORS 跨域问题

在 Spring Boot 应用中,解决跨域问题可以通过配置 CORS(Cross-Origin Resource Sharing)策略来实现。

以下是在 Spring Boot 中常用的几种解决跨域的方法:

1. 使用 @CrossOrigin 注解

在需要支持跨域的 Controller 类或方法上添加 @CrossOrigin 注解,允许指定源进行跨域访问。

import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@CrossOrigin(origins = "*", maxAge = 3600) // 允许所有来源访问,设置预检请求缓存有效期为3600秒
public class MyController {

    @GetMapping("/api")
    public String getData() {
        return "Hello, World!";
    }
}

2. 配置全局 CORS 过滤器

通过创建一个全局 CORS 过滤器,可以对所有 REST API 提供跨域支持。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

@Configuration
public class CorsConfig {

    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        
        // 设置允许跨域的源地址,* 表示允许任何源
        config.addAllowedOrigin("*");
        
        // 允许任何头信息
        config.addAllowedHeader("*");

        // 允许发送任何请求方法(如 GET、POST 等)
        config.addAllowedMethod("*");

        // 其他可选配置,例如预检请求的有效期等
        config.setMaxAge(3600L);

        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }
}

3. 使用 WebMvcConfigurer 实现类

通过扩展 WebMvcConfigurer 并重写其 addCorsMappings() 方法来自定义全局 CORS 规则。

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**") // 对所有路径生效
                .allowedOrigins("*") // 允许所有来源
                .allowedMethods("*") // 允许所有请求方法
                .allowCredentials(true) // 允许携带凭据(cookies等)
                .maxAge(3600); // 预检请求缓存有效期为3600秒
    }
}

根据项目需求选择合适的方式配置跨域策略,并确保正确处理安全风险。在生产环境中,应避免使用 * 允许所有来源,而应明确指定允许跨域的域名。

7.1.安装 Axios

7.1.1.在线地址

<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

7.1.2.VUE中使用

在 package.json 所在文件夹 执行

npm install axios

引入 axios 依赖包

import axios from "axios";

通过 components 声明

export default {
  components:{
    axios
  },
}

7.2.请求方式

7.2.1.标准写法

axios({
    method: "get",
    url: "http://localhost:8080/test/axiosMethod",
}).then((resp) => {
    console.log(resp);
}).catch( (error) => {
    console.log(error);
});

axios.request( { config } ) 等同于 axios( { config } )

其中 method 属性, 可以选择 get , post , put/patch , delete 参考 RESTful风格

也可以省略 默认是 get

7.2.2.简化写法

axios.get("http://localhost:8080/test/axiosMethod")
.then((resp) => {
    console.log(resp);
}).catch((error) => {
    console.log(error);
});

包括

axios.get( url [, config] ): 发 get 请求

axios.delete( url [, config] ): 发 delete 请求

axios.post( url [, data, config] ): 发 post 请求

axios.put( url [, data, config] ): 发 put 请求

axios.patch( url [, data, config] ): 发 patch 请求

后台Controller

import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/test/axiosMethod")
public class TggaMethodController {

    @GetMapping
    public String getMethod(){
        return "get";
    }
    @PostMapping
    public String postMethod(){
        return "post";
    }
    @PutMapping
    public String putMethod(){
        return "put";
    }
    @PatchMapping
    public String patchMethod(){
        return "patch";
    }
    @DeleteMapping
    public String deleteMethod(){
        return "delete";
    }
}

7.3. 传参数

7.3.1.url?name=value

// 传 1 个值 
axios({
     method: "delete",
     url: "http://localhost:8080/testParamUrl/param?name=wang"
 }).then((resp) => {
     console.log(resp);
 });
// 传多个值
axios({
    method: "delete" ,
    url: "http://localhost:8080/testParamUrl/params?name=王小二&age=18"
}).then((resp) => {
    console.log(resp);
});

后台Controller

import org.springframework.web.bind.annotation.*;


@RestController
public class TcccParamUrlController {

    /**
     * 传递参数 URL?
     */
    @PostMapping("/testParamUrl/param")
    public void paramPost(String name){
        System.out.println("name post= " + name);
        System.out.println("--end--");
    }

    @GetMapping("/testParamUrl/param")
    public void paramGet(String name){
        System.out.println("name get = " + name);
        System.out.println("--end--");
    }

    @PutMapping("/testParamUrl/param")
    public void paramPut(String name){
        System.out.println("name put = " + name);
        System.out.println("--end--");
    }

    @PatchMapping("/testParamUrl/param")
    public void paramPatch(String name){
        System.out.println("name patch = " + name);
        System.out.println("--end--");
    }

    @DeleteMapping("/testParamUrl/param")
    public void paramDelete(String name){
        System.out.println("name delete = " + name);
        System.out.println("--end--");
    }

}

7.3.2.params

相当于 url? 传参, 参数会显示在请求后面

// 传 1 个值 
axios({
    method: "get",
    url: "http://localhost:8080/testParamUrl/param",
    params: {
        name: "wang"
    }
}).then((resp) => {
    console.log(resp);
});
// 传多个值
axios({
    method: "put" ,
    url: "http://localhost:8080/testParamUrl/params",
    params: {
        name: "wang",
        age: 18
    }
}).then((resp) => {
    console.log(resp);
});

后台Controller 与 7.3.2.1. 相同

7.3.3.RESTful路径传参

axios({
    method: "get" ,
    url: "http://localhost:8080/testRestParam/paramOne/王小二",
}).then((resp) => {
    console.log(resp);
});

后台Controller 通过 @PathVariable 注解进行接值

import org.springframework.web.bind.annotation.*;

@RestController
public class TfffRestParamController {

    /**
     * 接 一参
     */
    @GetMapping("/testRestParam/paramOne/{name}")
    public void paramOneGet(@PathVariable String name){
        System.out.println("name get = " + name);
    }

    @PostMapping("/testRestParam/paramOne/{name}")
    public void paramOnePost(@PathVariable String name){
        System.out.println("name post = " + name);
    }

    @PutMapping("/testRestParam/paramOne/{name}")
    public void paramOnePut(@PathVariable String name){
        System.out.println("name put = " + name);
    }

    @PatchMapping("/testRestParam/paramOne/{name}")
    public void paramOnePatch(@PathVariable String name){
        System.out.println("name patch = " + name);
    }

    @DeleteMapping("/testRestParam/paramOne/{name}")
    public void paramOneDelete(@PathVariable String name){
        System.out.println("name delete = " + name);
    }

}

7.3.4.data传参

data 将信息封装到请求包里

7.3.4.1.传JSON对象

参数格式 application/json, 后台通过 @RequestBody 封装成实体类

axios({
    method: "put" ,
    url: "http://localhost:8080/testRestParam/paramObj",
    data: {
        name: "wang",
        age: 18
    }
}).then((resp) => {
    console.log(resp);
});

// 可以 简写成

axios.put("http://localhost:8080/testRestParam/paramObj" , {
    name: "wang",
    age: 18
})

后台Controller

import com.yuan.domain.Stu;
import org.springframework.web.bind.annotation.*;

@RestController
public class TfffRestParamController {

    /**
     * 接 对象 @RequestBody
     */
    @PostMapping("/testRestParam/paramObj")
    public void paramObjPost(@RequestBody Stu stu){
        System.out.println("stu post = " + stu);
    }


    /**
     * 接 对象 @RequestBody
     */
    @PutMapping("/testRestParam/paramObj")
    public void paramObjGet(@RequestBody Stu stu){
        System.out.println("stu put = " + stu);
    }


    /**
     * 接 对象 @RequestBody
     */
    @PatchMapping("/testRestParam/paramObj")
    public void paramObjPatch(@RequestBody Stu stu){
        System.out.println("stu patch = " + stu);
    }


    /**
     * 接 对象 @RequestBody
     */
    @DeleteMapping("/testRestParam/paramObj")
    public void paramObjDelete(@RequestBody Stu stu){
        System.out.println("stu delete = " + stu);
    }

    /**
     * 注意 get方式 接不到 报 400异常
     */
    @GetMapping("/testRestParam/paramObj")
    public void paramObjPut(@RequestBody Stu stu){
        System.out.println("stu get = " + stu);
    }

}

7.3.4.2.上传文件

通过 input 选择文件

<input id="fileInp" type="file" name="name" />

参数格式 multipart/form-data

let file = document.getElementById("fileInp").files[0]; // 文件对象

let param = new FormData(); // 创建form对象
param.append("file", file); // 通过append向form对象添加数据

param.append("other", "别的数据"); // 添加form表单中其他数据
console.log(param.get("file")); // FormData私有类对象,访问不到,可以通过get判断值是否传进去


axios({
    method: "post" ,
    url: "http://localhost:8080/testFormParam/paramsFile",
    data: param,
    headers: { "Content-Type": "multipart/form-data" }
}).then((resp) => {
    console.log(resp);
});

vue版本

let userData = {
    other: '其它信息',
    file: this.$refs.input.files[0], // 页面有  <input type="file" name="file" ref="input" />
};

let formData = new FormData();
for (let key in userData) {
    // console.log(key, userData[key])
    formData.append(key, userData[key]);
}
console.log(formData);
axios({
    method: "post",
    url: "http://localhost:8080/testFormParam/paramsFile",
    data: formData,
    headers: {
       "Content-Type": "multipart/form-data",
    },
}).then((resp) => {
    console.log(resp);
});

后台 Controller

@PostMapping("/testFormParam/paramsFile")
public void paramsFile(MultipartFile file, String other){
    System.out.println("file.name = " + file.getOriginalFilename());
    System.out.println("file.type = " + file.getContentType());
    System.out.println("other = " + other);
    System.out.println("--end--");
}

7.3.5. 传递数组

7.3.5.1.url?
axios({
    method: "post" ,
    url: "http://localhost:8080/testParamUrl/paramsArray?names=王小二&names=李小三&names=赵小四",
}).then((resp) => {
    console.log(resp);
});

后台Controller

@PostMapping("/testParamUrl/paramsArray")
public void paramsArray(String[] names){
    System.out.println("Arrays.toString(names) = " + Arrays.toString(names));
    System.out.println("--end--");
}
7.3.5.2.params 方式 接不到
axios({
    method: "post" ,
    url: "http://localhost:8080/testParamUrl/paramsArray",
    params: {
        names : ["王小二", "李小三", "赵小四"]
    }
}).then((resp) => {
    console.log(resp);
});

这样会报异常

java.lang.IllegalArgumentException: Invalid character found in the request target [/testParamUrl/paramsNames?names[]=wang&names[]=zhang&names[]=li ]. The valid characters are defined in RFC 7230 and RFC 3986

7.3.5.3.qs 字符串增强库

qs 是一个增加了一些安全性的查询字符串解析和序列化字符串的库。

在项目中使用命令行工具输入:

npm install qs

安装完成后在需要用到的组件中:

import qs from 'qs’

qs.parse()是将URL解析成对象的形式
qs.stringify()是将对象 序列化成URL的形式,以&进行拼接
indices: false可以取消URL里数组的下标,如果不这么处理,后端收不到这个数组(名字因为加了下标而不匹配)

qs.stringify({ids: [1, 2, 3]}, { indices: false })
 //形式: ids=1&ids=2&id=3
qs.stringify({ids: [1, 2, 3]}, {arrayFormat: ‘indices‘})
 //形式: ids[0]=1&aids[1]=2&ids[2]=3
qs.stringify({ids: [1, 2, 3]}, {arrayFormat: ‘brackets‘})
 //形式:ids[]=1&ids[]=2&ids[]=3
qs.stringify({ids: [1, 2, 3]}, {arrayFormat: ‘repeat‘}) 
//形式: ids=1&ids=2&ids=3

增加字符串处理函数

// 传递数组
axios.delete("http://localhost:8080/testParamUrl/paramsArray", {
    params: {
         names : ["王小二", "李小三", "赵小四"]
    },
    paramsSerializer: (params) => {
        return qs.stringify(params, { indices: false });
    },
});

或者

axios.post("http://localhost:8080/testParamUrl/paramsArray",
   	qs.stringify(
        {
             names : ["王小二", "李小三", "赵小四"]
        },
        { indices: false }
	) )
    .then((resp) => {
    console.log(resp);
});

后台 Controller 与 前面的相同

7.3.5.4.data传值 , 对象接值
axios({
    method: "post" ,
    url: "http://localhost:8080/testParamUrl/objectArray",
    params: {
        names : ["王小二", "李小三", "赵小四"]
    }
}).then((resp) => {
    console.log(resp);
});

或者

axios.post("http://localhost:8080/testParamUrl/objectArray" , {
    names : ["王小二", "李小三", "赵小四"]
})

后台 Controller接值

@PostMapping("/testParamUrl/objectArray")
public void objectArray(@RequestBody Stu stu){
    System.out.println("Arrays.toString(stu.getNames()) post = " + Arrays.toString(stu.getNames()));
    System.out.println("--end--");
}

接值的对象 实体类

import lombok.Data;

@Data
public class Stu {
	
    //... 其它属性
    
    private String[] names;
}

7.4. 配置信息

7.4.1.axios.create() 设置属性

axios.create() 方法是用来创建一个新的 Axios 实例,这个实例继承了 Axios 的核心功能,但可以拥有独立于默认配置之外的自定义配置。

通过这种方法,你可以在不同的场景下使用不同的基础 URL、请求头、超时时间等配置。

创建一个自定义 Axios 实例的基本语法如下:

const axiosObj = axios.create({
  baseURL: 'http://localhost:8080', // 自定义基础 URL
  timeout: 10000, // 请求超时时间(毫秒)
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer your-token'
  }, // 自定义请求头
  responseType: 'json', // 响应的数据类型,默认是 'json',也可以是 'arraybuffer', 'blob', 'document', 'text'
  validateStatus: function (status) {
    // 自定义 HTTP 状态码范围判断请求是否成功
    return status >= 200 && status < 300; // 默认标准
  },
  transformRequest: [function (data, headers) {
    // 在发送到服务器之前,可以在此处转换请求数据
    return data;
  }],
  transformResponse: [function (data) {
    // 在收到服务器响应之后,可以在此处转换数据
    return data;
  }],
});


以上示例中,我们创建了一个新的 Axios 实例,

并设置了基础 URL 为 'http://localhost:8080',设置了超时时间为 10000 毫秒,并定义了一些其他的请求和响应处理函数。

这样,后续通过 axiosObj 发起的所有请求都将使用这些自定义配置。

在 后续使用时, 使用创建的对象发请求, 并且请求url路径 不用写前面的部分, 相当于在前面拼接 baseURL 内容

axiosObj({
    method: "get",
    url: "/test/axiosMethod",
}).then((resp) => {
    console.log(resp);
}).catch( (error) => {
    console.log(error);
});

7.2.4.全局默认配置

7.2.4.1.设置默认属性

在 Axios 中,你可以设置全局默认的属性,这样在创建的所有请求中都会自动应用这些属性。

要设置 Axios 的默认属性,你需要在实例化 Axios 之前或者在创建自定义 Axios 实例时设置:

// 设置全局默认配置
axios.defaults.baseURL = 'https://api.example.com'; // 设置基础 URL
axios.defaults.timeout = 10000; // 设置超时时间
axios.defaults.headers.common['Authorization'] = 'Bearer yourToken'; // 设置公共请求头

通过 axios.defaults 对象,你可以配置的属性包括但不限于:

  • baseURL: 所有请求的默认基础 URL。
  • timeout: 请求的超时时间(毫秒)。
  • headers: 默认的请求头,可以覆盖 commongetpost 等不同方法类型的头部。
  • transformRequesttransformResponse: 请求数据和响应数据的转换函数。
  • validateStatus: 自定义 HTTP 状态码范围判断请求是否成功。
7.2.4.2.与create()同时使用时

create() 方法创建的自定义 Axios 实例会 继承全局的默认配置,同时也可以在其基础上进一步定制个性化的默认属性。

但在冲突的属性上( 两种方式都设置相同属性时 ),自定义实例会覆盖全局默认配置。

这是因为 axios.create() 会创建一个全新的 Axios 实例,并使用传入的配置对象覆盖或补充默认配置。

// 这个请求是通过 自定义Axios实例创建的, 
// 所以请求URL是: http://localhost:8080/test/axiosMethod
axiosObj({
    method: "get",
    url: "/test/axiosMethod",
}).then((resp) => {
    console.log(resp);
}).catch( (error) => {
    console.log(error);
});


// 这个请求是通过 默认的Axios实例创建的, 配置使用 全局默认配置
// 所以请求URL是: https://api.example.com/test/axiosMethod
axios({
    method: "get",
    url: "/test/axiosMethod",
}).then((resp) => {
    console.log(resp);
}).catch( (error) => {
    console.log(error);
});

7.4.3.请求参数***

{
  // `url` 是请求的接口地址
  url: '/user',

  // `method` 是请求的方法
  method: 'get', // 默认值

  // 如果url不是绝对路径,那么会将baseURL和url拼接作为请求的接口地址
  // 用来区分不同环境,建议使用
  baseURL: 'https://some-domain.com/api/',

  // 用于请求之前对请求数据进行操作
  // 只用当请求方法为‘PUT’,‘POST’和‘PATCH’时可用
  // 最后一个函数需return出相应数据
  // 可以修改headers
  transformRequest: [function (data, headers) {
    // 可以对data做任何操作

    return data;
  }],

  // 用于对相应数据进行处理
  // 它会通过then或者catch
  transformResponse: [function (data) {
    // 可以对data做任何操作

    return data;
  }],

  // `headers` are custom headers to be sent
  headers: {'X-Requested-With': 'XMLHttpRequest'},

  // URL参数
  // 必须是一个纯对象或者 URL参数对象
  params: {
    ID: 12345
  },

  // 是一个可选的函数负责序列化`params`
  // (e.g. https://www.npmjs.com/package/qs, http://api.jquery.com/jquery.param/)
  paramsSerializer: function(params) {
    return Qs.stringify(params, {arrayFormat: 'brackets'})
  },

  // 请求体数据
  // 只有当请求方法为'PUT', 'POST',和'PATCH'时可用
  // 当没有设置`transformRequest`时,必须是以下几种格式
  // - string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams
  // - Browser only: FormData, File, Blob
  // - Node only: Stream, Buffer
  data: {
    firstName: 'Fred'
  },

  // 请求超时时间(毫秒)
  timeout: 1000,

  // 是否携带cookie信息
  withCredentials: false, // default

  // 统一处理request让测试更加容易
  // 返回一个promise并提供一个可用的response
  // 其实我并不知道这个是干嘛的!!!!
  // (see lib/adapters/README.md).
  adapter: function (config) {
    /* ... */
  },

  // `auth` indicates that HTTP Basic auth should be used, and supplies credentials.
  // This will set an `Authorization` header, overwriting any existing
  // `Authorization` custom headers you have set using `headers`.
  auth: {
    username: 'janedoe',
    password: 's00pers3cret'
  },

  // 响应格式
  // 可选项 'arraybuffer', 'blob', 'document', 'json', 'text', 'stream'
  responseType: 'json', // 默认值是json

  // `xsrfCookieName` is the name of the cookie to use as a value for xsrf token
  xsrfCookieName: 'XSRF-TOKEN', // default

  // `xsrfHeaderName` is the name of the http header that carries the xsrf token value
  xsrfHeaderName: 'X-XSRF-TOKEN', // default

  // 处理上传进度事件
  onUploadProgress: function (progressEvent) {
    // Do whatever you want with the native progress event
  },

  // 处理下载进度事件
  onDownloadProgress: function (progressEvent) {
    // Do whatever you want with the native progress event
  },

  // 设置http响应内容的最大长度
  maxContentLength: 2000,

  // 定义可获得的http响应状态码
  // return true、设置为null或者undefined,promise将resolved,否则将rejected
  validateStatus: function (status) {
    return status >= 200 && status < 300; // default
  },

  // `maxRedirects` defines the maximum number of redirects to follow in node.js.
  // If set to 0, no redirects will be followed.
  // 最大重定向次数?没用过不清楚
  maxRedirects: 5, // default

  // `httpAgent` and `httpsAgent` define a custom agent to be used when performing http
  // and https requests, respectively, in node.js. This allows options to be added like
  // `keepAlive` that are not enabled by default.
  httpAgent: new http.Agent({ keepAlive: true }),
  httpsAgent: new https.Agent({ keepAlive: true }),

  // 'proxy' defines the hostname and port of the proxy server
  // Use `false` to disable proxies, ignoring environment variables.
  // `auth` indicates that HTTP Basic auth should be used to connect to the proxy, and
  // supplies credentials.
  // This will set an `Proxy-Authorization` header, overwriting any existing
  // `Proxy-Authorization` custom headers you have set using `headers`.
  // 代理
  proxy: {
    host: '127.0.0.1',
    port: 9000,
    auth: {
      username: 'mikeymike',
      password: 'rapunz3l'
    }
  },

  // `cancelToken` specifies a cancel token that can be used to cancel the request
  // (see Cancellation section below for details)
  // 用于取消请求?又是一个不知道怎么用的配置项
  cancelToken: new CancelToken(function (cancel) {
  })
}

7.4.4. 响应信息结构

响应信息的结构, 可以从 data 属性中 取出响应结构

{
  // 服务端返回的数据
  data: "get",

  // 服务端返回的状态码
  status: 200,

  // 服务端返回的状态信息
  statusText: 'OK',

  // 响应头
  // 所有的响应头名称都是小写
  headers: {
      content-length: "3"  // 返回长度
	  content-type : "application/json"  // 返回格式
  },

  // axios请求配置
  config: {...},

  // 请求信息
  request: {...}
}    

7.5.拦截器

Axios 拦截器允许我们在请求发送前(请求拦截器)和响应返回后(响应拦截器)执行自定义操作。

这对于全局处理错误、添加通用请求头、身份验证令牌管理、数据预处理等场景非常有用。

7.5.1.请求拦截器

请求拦截器会在请求发出之前执行,可以用来修改请求配置或者在发送请求前做一些准备工作,如添加认证信息、统一错误处理等。

axios.interceptors.request.use(
  config => {
    // 在发送请求之前做些什么
    // 例如,向每个请求添加一个自定义请求头
    config.headers.common['Authorization'] = getToken(); // 获取并添加 token
    return config; // 必须返回 config,否则请求会被中断
  },
  error => {
    // 对请求错误做些什么
    return Promise.reject(error);
  }
);

7.5.2.响应拦截器

响应拦截器会在接收到服务器响应后、数据传递给 then 或 catch 前执行。它可以用来统一处理响应数据、处理错误信息等。

axios.interceptors.response.use(
  response => {
    // 对响应数据做些什么
    // 例如,对所有成功的响应添加额外的信息
    if (response.status === 200) {
      return response.data;
    } else {
      // 处理非 200 状态码
      return Promise.reject(response);
    }
  },
  error => {
    // 对响应错误做些什么
    if (error.response.status === 401) {
      // 处理未授权错误,如跳转到登录页面
    }
    return Promise.reject(error);
  }
);

7.5.3.取消 拦截器

若要移除已添加的拦截器,可以调用 interceptors 上的 eject 方法:

// 定义一个( 将被取消的 ) 拦截器
let intc = axios.interceptors.request.use(
    (config) => {
        // 在发出请求之前
        return config;
    },
    (err) => {
        // 在请求错误时
        return Promise.reject(err);
    }
);

// 取消 定义的 intc 拦截器
axios.interceptors.request.eject(intc);

通过拦截器,开发者可以更加灵活和高效地管理应用程序中的网络请求和响应。

7.6.取消请求

在 Axios 中,你可以使用 CancelToken 功能来取消正在进行的 HTTP 请求。

CancelToken 是一个基于 promise 的取消机制,它允许你在请求发出后取消请求。

axios.CancelToken(): 用于创建取消请求的 token 对象

axios.isCancel(): 是否是一个取消请求的错误

axios.Cancel(): 用于创建取消请求的错误对象 , 当axios.CancelToken() 对象调用 cancel() 时,

​ 方法内部会创建一个 axios.Cancel 实例,并触发与该 CancelToken 关联的所有请求的取消。

7.6.1.创建一个 CancelToken 实例和一个取消函数:

/*
        声明取消函数,用于取消通过 CancelToken 创建的 HTTP 请求。
        在下面的第2步 通过这个函数 取消请求
         */
let cancel;

/*
        创建了一个 CancelToken 源,这个源包含两个属性:token 和 cancel。
        token 是一个 CancelToken 实例,可以传递给 Axios 请求;
        cancel 是一个函数,当调用它时,会触发与该 token 关联的所有请求的取消
         */
const source = axios.CancelToken.source();
cancel = source.cancel;

// 现在你可以将这个 CancelToken 传递给请求
axios.get("http://localhost:8080/test/axiosMethod", {
    cancelToken: source.token
})
    .then(response => {
    // 处理响应
})
    .catch(error => {
    /*
              在这里,我们首先检查 error 是否是由 Axios 取消请求产生的。
              如果是,axios.isCancel(error) 将返回 true,
              并在控制台打印出取消的消息和错误详情。
              如果不是由取消产生的错误,则可以按照常规方式处理其他类型的错误。
             */
    if (axios.isCancel(error)) {
        console.log('请求被取消', error.message);
    } else {
        // 处理其他错误
    }
});

7.6.2.当需要取消请求时,调用取消函数

// 在某个条件满足时,取消请求
if (取消条件为真) {
  cancel('取消请求.'); // 参数是取消请求的原因,可选
}

通过这种方式,你可以随时取消正在进行的请求,并在捕获错误时检查是否是因为取消而引发的错误。

另外,如果你有多个请求需要同时取消,可以共享同一个 CancelToken 实例。当取消这个实例时,所有关联的请求都会被取消。

7.7.并发请求

通过 在 Axios 中,axios.all() 方法,可以并发执行多个异步请求,并在所有请求都完成后返回一个 Promise。

这个 Promise 在所有传入的请求都成功时解析为包含所有请求结果的数组, 或者在有任何一个请求失败时拒绝。

使用 axios.spread()方法来接收这些结果

axios.all(promises): 用于批量执行多个异步请求

axios.spread(): 用来指定接收所有成功数据的回调函数的方法

// 定义两个异步请求
const axios1 = axios.get('http://localhost:8080/test/axiosMethod');
const axios2 = axios.get('http://localhost:8080/testParamUrl/param?name=wang');

// 使用 axios.all() 来并发执行这两个请求
axios.all([axios1, axios2])
.then(axios.spread((resp1, resp2) => {
    // 这里将在两个请求都成功完成后执行
    console.log(resp1);
    console.log(resp2);
}))
.catch(err => {
    // 如果任何一个请求失败,这里将捕获到错误
    console.error('异常:', err);
});
举报

相关推荐

0 条评论