• axios取消请求原理、拦截器原理- http状态码 - http请求方式


    ajax、axios相关的面试题

    面试题

    • axios的优点,axios和ajax的区别
    • 原生实现ajax,说一下怎么用ajax发送请求
    • ajax的封装,取消请求,使用ajax封装类似axios可以实现的拦截器功能
    • axios 的拦截器原理
    • 那axios是怎样取消请求的

    概述

    axios是什么?
    基于promise的异步ajax请求库

    axios有什么新特点?

    • 支持请求/响应拦截器 ★
    • 支持请求取消
    • .浏览器端(创建ajax请求)/node端(创建一般的HTTP请求)都可以使用
    • 请求/响应数据转换 --> 使用时写的是对象,axios自动转换成了json。接受时axios也自动将json转换为了对象

    axios拦截器原理

    拦截器的使用

    // 添加请求拦截器
    axios.interceptors.request.use(function (config) {
        // 在发送请求之前做些什么
        return config;
      }, function (error) {
      	  // 对请求错误做些什么
        return Promise.reject(error);
      });
    // 添加响应拦截器
    axios.interceptors.response.use(function (response) {
        // 对响应数据做点什么
        return response;
      }, function (error) {
        // 对响应错误做点什么
        return Promise.reject(error);
    });
    
    const interceptorId = axios.interceptors.request.use(function () {/*...*/}); 
    axios.interceptors.request.eject(interceptorId); 
    /*
    在axios对象属性中暴露出了一个interceptors这个属性对象,该对象有两个属性分别是request、response,这两个属性存分别对应请求前与请求后我们想做的一些操作,再调用use函数配置了两个函数进去。
    */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    拦截器原理: 本质是一个顺序问题 请求拦截器-api请求-响应拦截器

    1. 拦截器中,定义了handlers 数组收集了所有的拦截器方法。
    2. axios使用的是数组的方式完成了链式调用,通过request与response的forEach方法,将请求拦截器插入到chain(请求api)的前面,将响应拦截器插入到chain(请求api)的后面。
    3. 执行时从队头开始执行,所以请求拦截器后设置的先执行,响应拦截器先设置的先执行。
      在这里插入图片描述
    var promise = Promise.resolve(config);
      while (chain.length) {
        promise = promise.then(chain.shift(), chain.shift());
      }
    
    • 1
    • 2
    • 3
    • 4

    axios取消请求的原理

    取消请求的使用
    1.excutor执行器函数是同步执行的,参数是用于取消当前请求的函数
    2.当取消当前请求的函数被调用时,该请求会进入失败的流程,请求失败的error是Cancel对象类型,Cancel里面有message属性

    let cancel //保存用于取消请求的函数
    axios.get("/user",{
    	//new axios.CancelToken时得到一个函数
         cancelToken:new axios.CancelToken(function excutor(c){
    	 	cancel = c; //准备发请求时先把函数取消当前请求的函数存储起来
    	}).then(response =>{
            cancel = null; //如果请求完成就不要取消请求了
        },error =>{
    		cancel = null; 
    	})
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    取消请求的原理

    1. 怎么抛出取消函数的。
      同步执行器,执行器外部定义,内部执行。内部执行excutor函数的时候,传递取消请求函数。取消请求函数的作用将取消请求的promise指定为成功,值为Cancel对象。
      2.如何中断请求。
      当取消请求函数执行时,获取取消请求的promise状态,如果成功并且请求还没有执行完成则执行request.abort()中断请求,并调用reject(cancel对象)将请求的状态该为失败。
    function CancelToken(excutor){
    ///...
    let resolvePromise;
    //为取消请求准备一个promise对象,并保存resolve函数
    this.promise = new Promise(function promiseExecutor(resolve){
    	resolvePromise = resolve;
    })
    let token = this; //保存当前CancelToken对象
    //立刻执行同步执行器,执行器外部定义,内部执行
    excutor(function cancel(message){ //给excutor函数传参,参数为cancel函数
    	//....
    	//将token的reason指定为一个Cancel对象
    	token.reason = new Cancel(message);
    	resolvePromise(token.reason); //将取消请求的promise指定为成功,成功的值为reason
    })
    }
    
    //取消请求部分的代码
    if(config.cancelToken){
    	config.cancelToken.promise.then(function onCanceled(cancel){
    		request.abort();//中断请求
    		reject(cancel);
    		request = null'
    	})
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    手写ajax (简单的axios)

    1. 参数是option配置对象,返回promise对象
    2. 利用XHR对象发送ajax请求
      1. 创建xhr对象new XMLHttpRequest()
      2. 初始化xhr连接xhr.open(method,url,true) 默认async:true,参数是请求行
      3. 发送请求xmr.send() 参数为字符串,可以是json对象字符串,也可以是urlencoded格式字符串
      4. xml.onreadystatechange 用于监听请求状态的改变,send是异步的
        readyState 0:初始 1:open()之后 2:send()之后 3:请求中 4:请求完成
    3. 处理结果,返回status、statusText 以及响应数据,数据需要转换为字符串/对象格式
    function axios({
    	url,
    	method='GET',
    	params={},
    	data={},
    }){
    	return new Promise(resolve,reject){
        //数据初始化操作
        let query ='' ;
        Object.keys(params).forEach(key => {
            query += `${key}=${params[key]}&` 
        })
        if(query){
          query = query.substring(0,query.length-1);
          url = url + '?' + query;
        }
        method = method.toUpperCase();
        let xhr = new XMLHttpRequest() //创建xhr对象
        xhr.open(url,method); //初始化请求
    
        //状态监听,send是异步的
        xhr.onreadystatechange = function(){
          if(xhr.readyState !==4) return;
          //请求完成
          let {status,statusText} = xhr;
          if (status>=200&&status<=299){
            const response = {
              data:JSON.parse(xhr.response),
              status,
              statusText,
          }
          resolve(response)
          }else{
            reject(new Error(`request error status is ${status}`))
          }
        }
    
        switch(method){//发送请求
            case 'GET' || 'DELETE':
              xhr.send();
              break;
            case 'POST' || 'PUT':
              xhr.setRequestHeader("Content-Type","application/json;charset=utf");
              xhr.send(JSON.stringify(data));
        } 
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    XHR对象的常用方法或属性

    方法/属性描述
    readyState请求的状态 0:初始 1:open()之后 2:send()之后 3:请求中 4:请求完成
    onreadystatechange监视回调函数绑定readyState改变的监听 on…当…时执行
    open(method,url[,async])初始化一个请求 默认async:true,参数是请求行
    send(data)发送请求 参数为字符串,可以是json对象字符串,也可以是urlencoded格式字符串
    abort()中断请求 中断的是发出请求,还没结束的请求

    HTTP常用状态码

    面试题

    • http状态码:4xx和5xx的区别
    • 详细说下4xx的内容
    • 500和502的区别?
    • HTTP中302是啥?
    • 说一下304和301的区别?
    • 404 403 503?

    常用状态码

    状态码类别原因
    2XX成功状态码 Success请求正常处理完毕
    3XX重定向状态码 Redirection表示要完成请求,需要进一步操作(比如资源的url变了需要改变请求的url)
    4XX客服端错误状态码 Client Error服务器无法处理请求
    5XX服务器错误状态码 Server Error服务器处理请求出错

    3xx 重定向状态码

    状态码描述理解
    301 Moved Permanently永久重定向请求的资源已经被移动到新的URI,返回信息会包括新的URI
    302 Found临时移动,请求的资源被临时移动了希望本次使用新的URI访问
    304 Not Modified服务器端资源未修改,可直接使用客户端未过期的缓存可以结合http缓存回答

    4xx状态码 客户端错误状态码

    状态码描述理解
    400 Bad Request客户端请求的语法错误,服务器无法理解
    401 Unauthorized身份未认证两种情况
    1.服务端要求传递token信息,而实际发送请求时没有传递。
    2.发送请求时有传递token到达服务器端,但由于时间比较久,这个token在服务器中已经过期了
    403 Forbidden服务器理解请求客户端的请求,但是拒绝执行此请求
    404 Not Found服务器上没有请求的资源

    5xx状态码 服务器端错误状态码

    状态码描述理解
    500 Internal Server Error服务器内部错误,无法完成请求
    502 网关错误作为网关或者代理工作的服务器尝试执行请求时,从远程服务器接收到了一个无效的响应
    503 Service Unavailable服务器暂时处于超负载或正在进行停机维护。现在无法处理请求

    http常见请求方式

    面试题

    • get post请求的区别,get post哪个性能更好
    • 请求方法,options请求的作用
    方法描述
    head本质和get一样,但是响应中没有呈现数据,而是http的头信息,主要用来检查资源或超链接的有效性或是否可以可达、检查网页是否被串改或更新,获取头信息等,特别适用在有限的速度和带宽下。
    get从服务端获取数据
    post用于将数据发送到服务器来创建/更新资源
    put用于将数据发送到服务器来创建/更新资源 ,POST 和 PUT之间的区别多次调用相同的 PUT 请求将始终产生相同的结果,重复调用POST请求具有多次创建相同资源的副作用。
    delete删除指定的资源
    options获取http服务器支持的http请求方法,允许客户端查看服务器的性能,比如ajax跨域时的预检等。

    预检请求options

    对于跨域的非简单请求,浏览器会在正式通信之前,增加一次HTTP查询请求。使用 OPTIONS 方法发起一个预检(preflight)请求到服务器。
    目的是为了知道服务器是否允许该请求

    服务器成功响应预检请求后,浏览器才会发送真正的请求,并携带真实数据。

    • Origin:包含请求页面的源信息(协议、域名和端口),以便服务器根据这个头部信息来决定是否给予响应。
    • Access-Control-Request-Method: 请求自身使用的方法。
    • Access-Control-Request-Headers: (可选)自定义的头部信息,多个头部以逗号分隔

    服务器的响应头

    • Access-Control-Allow-Origin 允许跨域请求的域名
    • Access-Control-Allow-Methods 返回了服务端允许的请求,包含GET/HEAD/PUT/PATCH/POST/DELETE
    • Access-Control-Allow-Headers: 允许的头部,多个方法以逗号分隔。
    • Access-Control-Max-Age: 将这个 Preflifght 请求缓存多长时间(以秒表示)。

    options请求的优化: 将预检请求的缓存后,以后每次浏览器正常的 CORS 请求,就都跟简单请求一样了

    get和post的区别

    类型参数性能问题支持缓存请求方式
    get请求参数在url中,格式是key=value & key=valueGET请求只能进行url编码,参数的数据类型接收ASCII字符,回退无害get请求的响应结果会被浏览器缓存下来(一个get请求的路径对应一个资源)浏览器会把http header和data一并发送出去,服务器响应200
    post请求request body,在请求体当中发送post支持多种编码方式,参数的数据类型没有限制,回退再次提交请求不支持浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok

    GET产生一个TCP数据包;POST产生两个TCP数据包
    GET 请求过程
    1.浏览器发起请求 TCP 连接(第一次握手)
    2.服务器响应进行 TCP 连接(第二次握手)
    3.浏览器确认,并发送 GET 请求头和数据(第三次握手)
    4.服务器返回 200 OK响应

    POST 请求过程:
    1.浏览器发起请求 TCP 连接(第一次握手)
    服务器响应进行 TCP 连接(第二次握手)
    浏览器确认,并发送 POST 请求头(第三次握手)
    服务器返回100 Continue响应
    浏览器发送数据
    服务器返回 200 OK响应

    100:continue 客户端应当继续发送请求。这个临时响应是用来通知客户端它的部分请求已经被服务器接收,且仍未被拒绝。客户端应当继续发送请求的剩余部分

  • 相关阅读:
    分支创建&查看&切换
    容联云首发基于统信UOS的Rphone,打造国产化联络中心新生态
    技术管理者的管理框架
    C++ 之 C++11新特性
    ChatGPT AIGC 完成超炫酷的大屏可视化
    高考志愿冲稳保策略
    UE5 运行时生成距离场数据
    组合控件——底部标签栏——利用BottomNavigationView实现底部标签栏
    mkfifo函数 及 解决Linux下 “mkfifo: no such file or directory”
    PHP写一个 电商Api接口需要注意哪些?考虑哪些?
  • 原文地址:https://blog.csdn.net/qq_41370833/article/details/125969545