ajax、fetch、promise、axios、async/await
AJAX(Asynchronous Javascript And XML)异步JS和XML,是一种异步请求技术。ajax技术是实现网页的局部数据的刷新,你可以通过XHR、fetch、websocket等API实现。
Axios在NPM上的描述是:Promise based HTTP client for the browser and node.js,是一种基于promise用于浏览器和nodejs的HTTP客户端。Axios是通过promise实现XHR封装,其中promise是控制手段,xhr是实际发送Http请求的客户端。提供了一些并发请求的接口。
axios不支持jsonp(解决:方法1.服务器端设置 res.header(“Access-Control-Allow-Origin”, “*”); 方法2.给axios封装一个jsonp方法)。
axios.jsonp = (url,data)=>{
if(!url) throw new Error('url is necessary')
const callback = 'CALLBACK' + Math.random().toString().substr(9,18)
const JSONP = document.createElement('script')
JSONP.setAttribute('type','text/javascript')
const headEle = document.getElementsByTagName('head')[0]
let ret = '';
if(data){
if(typeof data === 'string')
ret = '&' + data;
else if(typeof data === 'object') {
for(let key in data)
ret += '&' + key + '=' + encodeURIComponent(data[key]);
}
ret += '&_time=' + Date.now();
}
JSONP.src = `${url}?callback=${callback}${ret}`;
return new Promise( (resolve,reject) => {
window[callback] = r => {
resolve(r)
headEle.removeChild(JSONP)
delete window[callback]
}
headEle.appendChild(JSONP)
})
}
本身具有以下特征:
- 从浏览器中创建XMLHttpRequest
- 从node.js发出http请求
- 支持Promise API
- 拦截请求和响应数据
- 取消请求
- 自动转换JSON数据
- 客户端支持防止CSRF/XSRF(防止CSRF:就是让你的每个请求都带一个从cookie中拿到的key, 根据浏览器同源策略,假冒的网站是拿不到你cookie中得key的,这样,后台就可以轻松辨别出这个请求是否是用户在假冒网站上的误导输入,从而采取正确的策略。)
- 提供了一些并发请求的接口
axios({
method:'post',
url:'',
data:{user:'admin',password:123456},
}).then((res)=>{
console.log(res)
}).catch(error=>{
console.log(error)
})
$.ajax是通过callback+XHR实现(对原生XHR的封装,还添加了对jsonp的支持)。缺点:本身是针对mvc的编程模式,不太适合MVVM编程模式。基于原生的XHR开发,XHR本身的架构不清晰,已经有了fetch的替代方案。多个请求之间如果有先后关系的话,就会出现回调地狱。
$.ajax({
url:'', //请求地址
type:'get', //请求类型:get或post
async:true, //默认是tue异步请求,false同步
data:{}, //向服务器发送请求时传的参数。如post请求时携带的用户名或者id。
dataType:'', //服务器响应的数据类型。默认(xml、json、script 或 html)
success(data){
console.log(data)
}
})
fetch机制,返回的是一个未处理的方法集合,我们可以通过这些方法得到我们想要的数据类型,想要json格式执行response.json(),想要字符串就response.text()。想要后台的数据需要.then()。fetch是一个低层次的API,需要进行封装。
fetch与axios的区别是response是一个综合各种方法的对象,并不是请求的数据。
- fetch只对网络请求报错,对400,500都当做成功的请求,服务器返回 400,500 错误码时并不会 reject,只有网络错误这些导致请求不能完成时,fetch 才会被 reject。
- fetch默认不会带cookie,需要添加配置项: fetch(url, {credentials: ‘include’})
- fetch不支持abort,不支持超时控制,使用setTimeout及Promise.reject的实现的超时控制并不能阻止请求过程继续在后台运行,造成了流量的浪费
- fetch没有办法原生监测请求的进度,而XHR可以
fetch('http://xxx/xxx.json?a=123').then(res => {
res.json().then((r)=>{//或者res.text()
console.log(r)//这里就是处理完的后台返回的json数据
})
})
发送普通json数据:
fetch('/xxx', {
method: 'post',
body: JSON.stringify({
username: '',
password: ''
})
});
发送form 表单数据
var form = document.querySelector('form');
fetch('/xxx', {
method: 'post',
body: new FormData(form)
});
获取图片
fetch('/xxx').then(res => {
return res.blob();
}).then(res => {
document.querySelector('img').src = URL.createObjectURL(imageBlob);
})
上传
var file = document.querySelector('.file')
var data = new FormData()
data.append('file', file.files[0])
fetch('/xxx', {
method: 'POST',
body: data
})
es6 的promise
逐步解决了层层回调的问题,es8的async
await
让异步变成了同步的写法
使用async await封装axios:
import axios from 'axios'
const qs = require('qs')
const api = {
async get(url,data){
try{
let res = await axios.get(url,{params:data})
res = res.data
return new Promise((resolve,reject)=> {
if(res.code === 0){
resolve(res)
}else {
reject(res)
}
})
}catch (err) {
console.log('服务器出错')
console.log(err)
}
},
async post(url,data){
try {
let res = await axios.post(url,qs.stringify(data))
res = res.data
return new Promise(((resolve, reject) => {
if(res.code === 0){
resolve(res)
}else {
reject(res)
}
}))
}catch (err) {
console.log('服务器出错')
console.log(err)
}
}
}
export {api}