ajax&axios / fetch&umi-request知识点

1. 异步和同步

异步和同步:客户端和服务器端相互通信的基础上

  • 同步:阻塞代码执行,即客户端必须等待服务器端的响应,在等待的期间客户端不能做其他操作。
  • 异步:不阻塞代码执行,即客户端不需要等待服务器端的响应,在服务器处理请求的过程中,客户端可以进行其他的操作。
    同步和异步

2. ajax:

1. 概念

Ajax:异步的JavaScript 和 XML(ASynchronous JavaScript And XML) 。Ajax是一种异步请求数据的web开发技术,在无需重新加载整个网页的情况下,Ajax 通过异步请求加载后台数据,能够更新部分网页。AJAX请求获取的是数据而不是HTML文档,因此它也节省了网络带宽,让互联网用户的网络冲浪体验变得更加顺畅。
Ajax技术的核心是XMLHttpRequest对象

2. XMLHttpRequest对象

XHR对象,用于与服务器交互数据,这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。XHR对象是ajax功能实现所依赖的对象,ajax就是对xhr对象的封装。

1. 创建XHR对象
var xmlhttp;
if (window.XMLHttpRequest){// code for IE7+, Firefox, Chrome, Opera, Safari
    xmlhttp=new XMLHttpRequest();
}else{// code for IE6, IE5
    xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
2. XHR对象的核心方法

XHR对象方法

3. XHR对象的核心属性
(1). XMLHttpRequest.onreadystatechange属性

只要 readyState 属性发生变化,就会调用相应的回调函数进行处理。XMLHttpRequest.onreadystatechange 会在 XMLHttpRequest 的readyState 属性发生改变触发 readystatechange 事件的时候被调用。

  • 用法:
    XMLHttpRequest.onreadystatechange = callback;
    当 readyState 的值改变的时候,callback 函数会被调用。
(2).XMLHttpRequest.readyState 属性

XMLHttpRequest.readyState 属性返回一个 XMLHttpRequest 代理当前所处的状态。

readyState属性可取值
0:未初始化。尚未调用open()方法
1:启动。已调用open()方法,但尚未调用send()方法
2:发送。已调用send()方法,但尚未接受到响应
3:接收。已接收到部分响应数据
4:完成。已接收到全部响应数据。而且客户端已经在使用了。

(3). XMLHttpRequest.status属性
(4). responseText / responseXML

如需获得来自服务器的响应,使用 XMLHttpRequest 对象的 responseText 或 responseXML 属性。
服务器响应数据

3. 原生js操作XHR对象,与后台服务器进行数据交互
//*******例:get请求*******
//1.创建XHR对象
var xmlhttp;
if (window.XMLHttpRequest){// code for IE7+, Firefox, Chrome, Opera, Safari
    xmlhttp=new XMLHttpRequest();
}else{// code for IE6, IE5
    xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
//2. 建立连接
/*
参数:
    2.1. 请求方式:GET、POST。。。
    2.2. 请求的URL:
    2.3. 同步或异步请求:true(异步)或 false(同步)

 */
xmlhttp.open("GET","ajaxServlet?username=tom",true);

//3.发送请求
xmlhttp.send();

//4.接受并处理来自服务器的响应结果
//当xmlhttp对象的就绪状态改变时,触发事件onreadystatechange。
xmlhttp.onreadystatechange=function(){
    //判断readyState就绪状态是否为4,判断status响应状态码
    if (xmlhttp.readyState==4){
    	if((xmlhttp.status>=200&&xmlhttp.status<300)||xmlhttp.status==304){
	       //获取服务器的响应结果
	        var responseText = xmlhttp.responseText;
	        alert(responseText);
	    }else{
	    	alert("失败");
	    }
	}
}
4. 手写ajax ---- 封装XHR
/*
options的属性和方法:
url表示请求地址
method表示请求方法
async表示是否是异步请求
data表示请求参数
success()成功的回调
error()失败的回调
*/
function ajax(options){
	//0.处理请求参数
	const res = [];
	for(var key in options.data){
	  res.push(key + "=" + data[key]);
	}
	let myParam = res.join("&")
	//1.创建XHR对象
	var xmlhttp;
	if (window.XMLHttpRequest){// code for IE7+, Firefox, Chrome, Opera, Safari
	    xmlhttp=new XMLHttpRequest();
	}else{// code for IE6, IE5
	    xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
	}
	if(options.method.toLowerCase() == 'get'){
		//2. 建立连接
		xmlhttp.open("GET",options.url+"?"+myParam,options.async);
		
		//3.发送请求
		xmlhttp.send();
	}else{
		//2. 建立连接
		xmlhttp.open("POST",options.url,options.async);
		xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded")
		//3.发送请求
		xmlhttp.send(myParam);
	}
	
	//4.接受并处理来自服务器的响应结果
	//当xmlhttp对象的就绪状态改变时,触发事件onreadystatechange。
	xmlhttp.onreadystatechange=function(){
	    //判断readyState就绪状态是否为4,判断status响应状态码
	    if (xmlhttp.readyState==4){
	    	if(xmlhttp.status>=200&&xmlhttp.status<300){
		        options.success(xmlhttp.responseText);
		    }else{
		    	options.error(xmlhttp.responseText);
		    }
		}
	}
}

//***********调用自己封装的ajax*************
ajax({
	//请求的url地址
    url:"http://www.microsoft.com",    
    //请求方式
    method:"POST", 
    //请求是否异步,默认为异步,这也是ajax重要特性  
    async:true,
    //参数值
    data:{"id":"value"},
    success:function(req){
        //请求成功时处理
    },
    error:function(req){
        //请求出错处理
    }
});
5. jquery中的ajax使用
  • jquery中的ajax使用
    $.ajax({
    	//请求的url地址
        url:"http://www.microsoft.com",    
        //请求方式
        type:"POST", 
        //请求是否异步,默认为异步,这也是ajax重要特性  
        async:true,
        //参数值
        data:{"id":"value"},    
        //返回格式为json
        dataType:"json", 
        beforeSend:function(){
            //请求前的处理
        },
        success:function(req){
            //请求成功时处理
        },
        complete:function(){
            //请求完成的处理
        },
        error:function(){
            //请求出错处理
        }
    });
    

3. axios

axios是前端最流行的ajax请求库,是对ajax的再次封装

(1). axios特点 / 优点
  1. 从浏览器中创建 XMLHttpRequests
  2. 从 node.js 创建 http 请求
  3. 支持 Promise API
  4. 拦截请求和响应
  5. 转换请求数据和响应数据
  6. 取消请求
  7. 自动转换 JSON 数据
  8. 客户端支持防止CSRF
(2). vue项目中简单使用axios
  1. 结合vue-axios使用
    vue-axios用于将axios集成到Vuejs的小包装器

    //1. 安装
    /*
    npm install --save axios
    npm install --save vue-axios
    */
    //2. 在主入口文件main.js中引用
    import axios from 'axios'
    import VueAxios from 'vue-axios'
    Vue.use(VueAxios,axios);
    
    //3. 使用axios ------- this.axios
    //例:
    methods:{
    	getNewsList(){
          this.axios.get('api/getNewsList').then((response)=>{
            this.newsList=response.data.data;
          }).catch((response)=>{
            console.log(response);
          })
        }
    }
    
  2. axios 改写为 Vue 的原型属性

    //1. 安装
    /*
    npm install --save axios
    */
    //2. 在主入口文件main.js中引用
    import axios from 'axios'
    //3. axios挂在vue的原型链上
    Vue.prototype.$axios= axios
    
    //3. 使用axios ------- this.$axios
    //例:
    methods:{
    	getNewsList(){
          this.$axios.get('api/getNewsList').then((response)=>{
            this.newsList=response.data.data;
          }).catch((response)=>{
            console.log(response);
          })
        }
    }
    
(3). vue中axios封装(全局请求处理)以及api接口统一管理
1. 如何封装axios
  1. 在src目录下新建一个request.js文件,引入axios并对其进行封装。
  2. 创建axios实例
  3. 根据不同的项目环境比如开发环境、测试环境和生产环境,设置axios的baseUrl
  4. 设置请求超时时间
  5. 设置请求头
  6. 设置请求和响应拦截,可以在响应拦截中对一些请求错误做一些处理。
  7. 最后将axios实例暴漏出来。
// 简单示例

import axios from 'axios'
import { Message } from 'element-ui'

// 创建axios实例
const service = axios.create({
  baseURL: process.env.BASE_API, // api的base_url
  timeout: 30000 // 请求超时时间
})

// request拦截器
service.interceptors.request.use(config => {
  // 判断是否有token[是否登陆了]
  if (token) {
    config.headers['Authorization'] = token // 让每个请求携带自定义token 请根据实际情况自行修改
    config.headers['Accept'] = 'application/json'
  }
  return config
}, error => {
  console.error(error) // for debug
  Promise.reject(error)
})

// respone拦截器
service.interceptors.response.use(
  response => {
    // 什么状态码能进到这里?
    if (response.status === 200 || response.status === 201 || response.status === 204) {
      return response.data
    } else {
      console.warn(response)
      const res = response
      Message({
        message: res.code + res.message,
        type: 'error',
        duration: 1.5 * 1000
      })
    }
    const res = response.data
    // 50008:非法的token; 50012:其他客户端登录了;  50014:Token 过期了;
    if (res.code === 50008 || res.code === 50012 || res.code === 50014) {
      MessageBox.confirm('你已被登出,可以取消继续留在该页面,或者重新登录', '确定登出', {
        confirmButtonText: '重新登录',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        store.dispatch('FedLogOut').then(() => {
          location.reload()// 为了重新实例化vue-router对象 避免bug
         })
       })
     }
      return Promise.reject('error')
    } else {
      return response.data
    }
  },
  error => {
    console.warn('err in service.interceptors.response' + error)
    return Promise.reject(error)
  }
)

export default service

2. 如果后端 token 失效,你会怎么做

项目中若前端未对token过期进行处理,token过期后仍然会停留在原页面,用户可以进行一系列的操作。但是由于后端有进行token过期的判断,会造成用户的所有请求报401错误。一般vue项目会对axios进行封装,在项目中src\utils目录下的request.js文件中进行错误处理,与后端商议好token过期的错误状态码,然后进行判断即可。

(4). axios拦截器
  • axios作用流程

axios作用流程

<script>
	/*
	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);
	  });
	 
	*/
	
	  
	  /*
	   * 手动实现axios拦截器的大概逻辑
	   */
	  function axios(){
	  	this.interceptors = {
	  		//InterceptorsManager就是拦截器对象构造函数
	  		request:new InterceptorsManager(),
	  		response:new InterceptorsManager() 
	  	}
	  }
	  axios.prototype.request = function(){
	  	  // chain是一个数组,存储整个axios作用流程的所有操作,dispatchRequest是真正的请求操作
		  var chain = [dispatchRequest, undefined];
		  var promise = Promise.resolve();
		  
		  // 请求拦截器处理
		  this.interceptors.request.handler.forEach((interceptor)=>{
		    //请求拦截器处理放在真正的请求之前
		    chain.unshift(interceptor.fulfilled, interceptor.rejected);
		  });
		  // 响应拦截器处理
		  this.interceptors.response.handler.forEach((interceptor)=>{
		    //响应拦截器处理放在真正的请求之后
		    chain.push(interceptor.fulfilled, interceptor.rejected);
		  });
		
		  //遍历chain数组,使用promise链式调用依次执行所有操作
		  while(chain.length){
		  	promise = promise.then(chain.shift(),chain.shift());
		  }
		  return promise;
	  }
	  
	  function InterceptorsManager(){
	  	//存储拦截器设置的处理
	  	this.handler = [];
	  }
	  InterceptorsManager.prototype.use = function(fullfilled,rejected){
	  	this.handler.push({
	  		fullfilled:fullfilled,
	  		rejected:rejected
	  	})
	  }
	  
	 /*
	   * axios请求方法注册
	   * axios所有请求都是调用request方法来实现的
	   */
	  const methods = ['get','post','delete'];
	  methods.forEach((method)=>{
	  	axios.prototype[method] = function(){
	  		//调用axios的request方法
	  		this.request(method)
	  	}
	  })
</script>

4. fetch

fetch是一种HTTP数据请求的方式,是浏览器提供原生的api,是XMLHttpRequest的一种替代方案。fetch不是ajax的进一步封装,而是原生js。

一、fetch优势:

  1. 语法简洁,更加语义化
  2. 基于标准 Promise 实现,支持 async/await
  3. 比较底层,提供的API丰富(request, response)
  4. 脱离了XHR,是ES规范里新的实现方式

二、fetch存在问题

  1. fetch是一个原生的API,所以使用起来并不是那么舒服,需要进行封装。
  2. fetch只对网络请求报错,对400,500都当做成功的请求,服务器返回 400,500 错误码时并不会 reject,只有网络错误这些导致请求不能完成时,fetch 才会被 reject。
  3. fetch默认不会带cookie,需要添加配置项: fetch(url, {credentials: ‘include’})
  4. fetch不支持中断请求,也不支持超时控制,使用setTimeout及Promise.reject的实现的超时控制并不能阻止请求过程继续在后台运行,造成了流量的浪费
  5. fetch没有办法原生监测请求的进度,而XHR可以

umi-request

umi-request 是基于 fetch 封装的开源 http 请求库

5. 面试相关

  • 前端发请求的技术有哪些?阐述他们的优缺点有哪些?
    axios和fetch

一、axios特点 / 优点

  1. 从浏览器中创建 XMLHttpRequests
  2. 从 node.js 创建 http 请求
  3. 支持 Promise API
  4. 拦截请求和响应
  5. 转换请求数据和响应数据
  6. 取消请求
  7. 自动转换 JSON 数据
  8. 客户端支持防止CSRF

二、fetch优势:

  1. 语法简洁,更加语义化
  2. 基于标准 Promise 实现,支持 async/await
  3. 比较底层,提供的API丰富(request, response)
  4. 脱离了XHR,是ES规范里新的实现方式

三、fetch存在问题

  1. fetch是一个原生的API,所以使用起来并不是那么舒服,需要进行封装。
  2. fetch只对网络请求报错,对400,500都当做成功的请求,服务器返回 400,500 错误码时并不会 reject,只有网络错误这些导致请求不能完成时,fetch 才会被 reject。
  3. fetch默认不会带cookie,需要添加配置项: fetch(url, {credentials: ‘include’})
  4. fetch不支持中断请求,也不支持超时控制,使用setTimeout及Promise.reject的实现的超时控制并不能阻止请求过程继续在后台运行,造成了流量的浪费
  5. fetch没有办法原生监测请求的进度,而XHR可以
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值