ajax、axios、fetch
XMLHttpRequest:
XHR中文解释为:
可扩展超文本传输请求;XML可扩展标记语言,Http超文本传输协议,Request请求;
XHR对象用于与服务器交换数据,所有现代游览器都支持XHR对象;XHR对象可在不向服务器提交整个页面的情况下,实现局部更新网页。
XHR可以同步或异步返回Web服务器的响应;XHR可以接收任何形式的文本文档;
使用XMLHttpRequest:
创建XHR对象:
const xhr = new XHLHttpRequest();
准备发送请求:
xhr.open(method,url,async); -method:请求类型 GET、POST、PUT、DELETE;- url:地址, - async:异步true或同步false
发送请求:
xhr.send() -send(‘username=Du&age=18’)的参数是通过请求体携带的数据 (字符串);
-GET请求只能通过请求头携带;-POST请求主要通过请求体携带数据,也可以通过请求头
POST请求需要设置请求头: xhr.setRequestHeader(“Content-type”,“application/x-www-form-urlencoded”);
携带的数据如果是非英文字母,如汉字、对象等,需要经过编码再发送;编码:encodeURLComponent(***);解码:decodeURLComponent(***)
监听事件,处理响应:
获得响应后,会触发xhr对象的readystatechange事件;
xhr.onreadystatechange = () => { if(xhr.readyState !==4) return;
if((xhr.status >=200 && xhr.status < 300) || xhr.status ===304){ console.log(xhr.responseText)} }
}
这个事件监听readyState这个状态的变化:
-
-
- 0:未初始化。尚未调用open()
- 1:启动。已经调用open(),但尚未受到send()
- 2:发送。已经调用send(),但尚未接收到响应
- 3:接收。已经接收到部分响应数据
- 4:完成。已经接收到全部响应数据,而且已经可以在页面中使用
-
status:HTTP状态码
-
-
- 100-199:信息性的标示用户应该采取的其他动作。
- 200-299:表示请求成功。
- 300-399:用于那些已经移走的文件,常常包括Location报头,指出新的地址。
- 400-499:表明客户引发的错误。
- 500-599:由服务器引发的错误。
-
Ajax:
Ajax:是 Asynchronous JavaScript and XML (异步 JavaScript 和 XML) 的简写
Ajax中的异步:可以异步地向服务器发送请求,在等待响应地过程中,不会阻塞当前页面,游览器可以继续执行同步任务,在同步任务全部执行完成后,再处理任务队列中的结果
XML(可扩展标记语言):是前后端数据通信时传输数据的一种格式,XML现在已经不怎么使用了,比较常用的是JSON
Ajax想要实现游览器与服务器之间的异步通信,需要借助XMLHttpRequest (Ajax就是基于浏览器提供的XMLHttpRequest对象)
axios:
axios,基于Promise的网络请求库,作用于node.js(http模块)和游览器(XMLHttpRequest)中(它是isomorphic的,即同一套代码可以运行在游览器和node.js)
本质上也是对原生XHR的封装,只不过它是Promise的实现版本,符合最新的ES规范;
特点:
-
-
从浏览器创建 XMLHttpRequests
-
从 node.js 创建 http 请求
-
支持 Promise API
-
拦截请求和响应
-
转换请求和响应数据
-
取消请求
-
自动转换JSON数据
-
客户端支持防御XSRF(CSRF)
-
axios.get('/user', { params: { ID: 12345 } }) .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); }) .then(function () { // 总是会执行 }); // 支持async/await用法 async function getUser() { try { const response = await axios.get('/user?ID=12345'); console.log(response); } catch (error) { console.error(error); } }
第二个参数和fetch一样都可以进行参数配置;
axios拦截器:
拦截器:分为请求(request)拦截器和响应(response)拦截器。
原理:创建一个数组,数组中保存了拦截器相应方法以及dispatchRequest(dispatchRequest这个函数调用才会真正的开始发起请求)
把请求拦截器的方法放到数组中dispatchRequest的前面,响应拦截器放到dispatchRequest的后面
为了保证它们的顺序,需要使用promise,以出队列的方式对数组中的方法挨个执行
应用场景:请求拦截器用于在接口请求之前做的处理,比如为每个请求带上相应的参数(token,时间戳等)
返回拦截器用于在接口返回之后做的处理,比如对返回的状态进行判断(token是否过期)
fetch:
fetch是一种HTTP数据请求方式,是XMLHttpRequest的一种替代方案
fetch函数就是原生js,没有使用XMLHttpRequest对象,
fetch()方法调用后返回一个Promise对象
fetch(url, {}).then(response => { console.log(response); if (response.ok || (response.status >= 200 && response.status <= 300)) { return response.json() } else { throw new Error(`HTTP CODE异常${response.status}`); } }).then(data => { console.log(data); }).catch(err => { console.log(err); })
Response 对象的同步属性:请求成功后,得到一个Response对象,它对应服务器的HTTP回应:
Response.ok:返回一个布尔值,表示请求是否成功;true对应HTTP请求状态码200~299,false对应其他状态码
Response.status:返回HTTP状态码
注意:只有网络错误或者无法连接时,fetch()才会报错,其它情况都认为请求成功,也就是服务器返回的状态码是4xx或5xx也不会报错(Promise不会变成rejected)
Response.statusText:返回一个字符串,表示HTTP回应的状态信息,例如请求成功以后,预览器返回‘OK’
Response.url:返回请求的URL,若存在跳转则为最终的URL
Response.type:返回请求的类型
-
-
- basic:普通请求,即同源请求
- cors:跨域请求
- error:网络错误,主要用于Service Worker
- opaque:如果fetch()请求的type属性设为no-cors,就会返回这个值,详见请求部分。表示发出的是简单的跨域请求,类似<from>表单的那种跨域请求。
- opaqueredirect:如果fetch()请求的redirect属性设为manual,就会返回这个值,详见请求部分
-
Response.redirected:返回一个布尔值,表示请求是否发生过跳转
Response.header():指向一个Header对象,对应HTTP回应所有标头
-
-
- Heade.get():根据指定的键名,返回键值。
- Header.has(): 返回一个布尔值,表示是否包含某个标头。
- Header.set():将指定的键名设置为新的键值,如果该键名不存在则会添加。
- Header.append():添加标头。
- Header.delete():删除标头。
- Header.keys():返回一个遍历器,可以依次遍历所有键名。
- Header.values():返回一个遍历器,可以依次遍历所有键值。
- Header.entries():返回一个遍历器,可以依次遍历所有键值对([key,value])。
- Header.forEach():依次遍历标头,每个标头都会执行一次参数函数。
-
读取服务器返回的不同类型数据:
-
-
- response.text():得到文本字符串。
- response.json():得到 JSON 对象。
- response.blob():得到二进制 Blob 对象。
- response.forData():得到 FormData 表单对象。
- response.arrayBuffer():得到二进制 ArrayBuffer 对象,主要用于获取流媒体文件
-
上述5中读取方法都是异步的,返回的都是Promise对象,必须等异步任务结束后,才能得到服务器返回的完整数据
Response.clone():Stream对象只能读取一次,这意味着上面的5个读取方法只能使用一个,否则会报错;response.clone()创建Response对象副本,实现多次读取
Response.redirect():重定向到指定URL
Response.body():Response.body属性是Response对象暴露出的底层接口,返回一个ReadableStream对象,供用户操作;可用来读取内容,应用之一就是显示下载的进度
fetch()第二个参数:
const response = await fetch(url, { method: 'POST', headers: { "Content-type": "application/x-www-form-urlencoded; charset=UTF-8", // 纯文本 "Content-Type": "application/json;charset=utf-8" // JSON },
bodyUsed:ture // 只读一次 // body: 'foo=bar&lorem=ipsum', // POST请求体 // body: JSON.stringify(user), // 提交JSON数据 // body: new FormData(form), // 提交表单 body: blob // 二级制数据 }); const json = await response.json();
XMLHttpRequest的问题:
所有的功能全部集中在一个对象上,容易书写混乱而且不容易维护的代码;采用传统的事件驱动模式,无法适配新的Promise API
XHR对象不支持数据流,所有的数据必须放在缓存中,不支持分块读取,必须等待全部拿到后,再一次性吐出来
fetch API的特点:
精细的功能分割:头部信息,请求信息,响应信息等API分散在多个对象上(Response、Request、Headers对象),更利于处理各种复杂的数据交互场景;
支持Promise API,更利于异步代码的书写;在某些服务不需要cookie的场景下可以自定义不携带cookie,减少一些些流量
fetch()通过数据流(Stream对象)处理数据,可以分块读取,有利于提高网站性能表现,减少内存占用,对于请求大文件或者网速慢的场景效果很好。
参考:
https://www.cnblogs.com/wenkangIT/p/15230842.html
https://baike.baidu.com/item/axios/56933453?fr=aladdin