axios面试题

axios是什么

  1. Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。前端最流行的 ajax 请求库
  2. react/vue 官方都推荐使用 axios 发 ajax 请求

axios特点

  1. 基于 promise 的异步 ajax 请求库,支持promise所有的API
  2. 浏览器端/node 端都可以使用,浏览器中创建XMLHttpRequests,在node.js中发送http请求
  3. 支持请求/响应拦截器
  4. 支持请求取消
  5. 可以转换请求数据和响应数据,并对响应回来的内容自动转换成 JSON类型的数据
  6. 批量发送多个请求
  7. 安全性更高,客户端支持防御 XSRF,就是让你的每个请求都带一个从cookie中拿到的key, 根据浏览器同源策略,假冒的网站是拿不到你cookie中得key的,这样,后台就可以轻松辨别出这个请求是否是用户在假冒网站上的误导输入,从而采取正确的策略。

axios 常用语法

axios(config): 通用/最本质的发任意类型请求的方式
axios(url[, config]): 可以只指定 url 发 get 请求
axios.request(config): 等同于 axios(config)
axios.get(url[, config]): 发 get 请求
axios.delete(url[, config]): 发 delete 请求
axios.post(url[, data, config]): 发 post 请求
axios.put(url[, data, config]): 发 put 请求
axios.defaults.xxx: 请求的默认全局配置
axios.interceptors.request.use(): 添加请求拦截器
axios.interceptors.response.use(): 添加响应拦截器
axios.create([config]): 创建一个新的 axios(它没有下面的功能)
axios.Cancel(): 用于创建取消请求的错误对象
axios.CancelToken(): 用于创建取消请求的 token 对象
axios.isCancel(): 是否是一个取消请求的错误
axios.all(promises): 用于批量执行多个异步请求
axios.spread(): 用来指定接收所有成功数据的回调函数的方法

axios为什么既能在浏览器环境运行又能在服务器(node)环境运行?

axios在浏览器端使用XMLHttpRequest对象发送ajax请求;在node环境使用http对象发送ajax请求。

var defaults.adapter = getDefaultAdapter();
function getDefaultAdapter () {
	var adapter;
    if (typeof XMLHttpRequest !== 'undefined') {
    	// 浏览器环境
        adapter = require('./adapter/xhr');
    } else if (typeof process !== 'undefined') {
    	// node环境
        adapter = require('./adapter/http');
    }
   return adapter;
}

上面几行代码,可以看出:XMLHttpRequest 是一个 API,它为客户端提供了在客户端和服务器之间传输数据的功能;process 对象是一个 global (全局变量),提供有关信息,控制当前 Node.js 进程。原来作者是通过判断 XMLHttpRequestprocess 这两个全局变量来判断程序的运行环境的,从而在不同的环境提供不同的 http 请求模块,实现客户端和服务端程序的兼容。

axios怎么区分客户端和服务器端的请求?

axios相比原生ajax的优点

ajax的缺点

本身是针对MVC的编程,不符合现在前端MVVM的浪潮
基于原生的XHR开发,XHR本身的架构不清晰。
JQuery整个项目太大,单纯使用ajax却要引入整个JQuery非常的不合理(采取个性化打包的方案又不能享受CDN服务)
不符合关注分离(Separation of Concerns)的原则
配置和调用方式非常混乱,而且基于事件的异步模型不友好。

axios拦截器的原理

function Axios(){
    this.interceptors = {
        //两个拦截器
        request: new interceptorsManner(),
        response: new interceptorsManner()
    }
}
//真正的请求
Axios.prototype.request = function(){
    let chain = [dispatchRequest, undefined];//这儿的undefined是为了补位,因为拦截器的返回有两个
    let promise = Promise.resolve();
    //将两个拦截器中的回调加入到chain数组中
    this.interceptors.request.handler.forEach((interceptor)=>{
        chain.unshift(interceptor.fulfilled, interceptor.rejected);
    })
    this.interceptors.response.handler.forEach((interceptor)=>{
        chain.push(interceptor.fulfilled, interceptor.rejected);
    })
    while(chain.length){
        //promise.then的链式调用,下一个then中的chain为上一个中的返回值,每次会减去两个
        //这样就实现了在请求的时候,先去调用请求拦截器的内容,再去请求接口,返回之后再去执行响应拦截器的内容
        promise = promise.then(chain.shift(),chain.shift());
    }
}
function interceptorsManner(){
    this.handler = [];
}
interceptorsManner.prototype.use = function(fulfilled,rejected){
    //将成功与失败的回调push到handler中
    this.handler.push({
        fulfilled: fulfilled,
        rejected: rejected
    })
}
//类似方法批量注册,实现多种请求
util.forEach(["get","post","delete"],(methods)=>{
    Axios.prototype[methods] = function(url,config){
        return this.request(util.merge(config||{},{//合并
            method: methods,
            url: url
        }))
    }
})

构造函数Axios的interceptors属性里定义了两个拦截器(request和response),都是通过new interceptorsManner(),interceptorsManner函数里有一个handler属性,是一个数组,它的原型对象上还有一个use方法,用来将成功与失败的回调push到handler中。Axios原型对象上的request方法发送请求,定义了一个chains数组,包含了两个元素(dispatchRequest和undefined,dispatchRequest是用来发送请求的,undefined是为了补位的,因为拦截器的返回有两个),将两个拦截器中的回调加入到chain数组中(将请求拦截器的回调 压入unshift到 chains 的前面,将响应拦截器的回调压入push到chains的后面),遍历chains数组,返回promise对象。

axios怎么封装的,优点,请求拦截有添加吗

如何取消未完成的请求?

  1. 当配置 了cancelToken 对象时

    (1) 创建一个用于将来取消请求的cancelPromise

    (2) 并定义了一个用于取消请求的cancel函数

    (3) 将cancel函数传递出来

  2. 调用cancel()取消请求

    (1) 执行cacel函数,传入错误信息message

    (2) 内部会让cancelPromise变为成功,且成功的值为一个 Cancel对象

    (3) 在cancelPromise的成功回调中中断请求,并让发请求的proimse失败,失败的reason为Cacel对象

你可能感兴趣的:(前端,javascript)