Axios | Ajax | Await|Async | asyncData | fetch

Axios vs Ajax

Axios

  • 基于promise的HTTP库。用在浏览器和node.js中

安装

  • npm install axois

使用: axios(config) || axios(url[, config])

//创建请求
axios({
  method:' post ',
  url:   theurl,
  data: {
        firstName:'Fred',
        lastName:'Fline'
  }
})
//GET请求
axios
.get(url , {params:{ID:12345}})
.then(function(response){})
.catch(function(error){});
//POST请求
axios
.post(url,{firstName:'Fred',laseName:'Fline'})
.then(function(response){})
.catch(function(error){})\

特殊使用:执行多个并发请求

function getUserAccount(){
  return axios.get(url1);
}
function getUserPermissions(){
  return axios.get(url2);
}
axios
.all([  getUserAccount(), getUserPermission()  ])
.then(  axios.spread(function(acct,perms){
    //两个请求都执行完成
})  )

API

  • axios.request(config)
  • axios.get(url[, config])
  • axios.delete(url[, config])
  • axios.head(url[, config])
  • axios.post(url[, data[, config]])
  • axios.put(url[, data[, config]])
  • axios.patch(url[, data[, config]])

处理并发请求的函数

  • axios.all()
  • axios.spread(callback)

创建实例: axios.create([config])

  • config{baseURL:'',timeout:2000,header:{'X-Custom-Header' : 'foobar' }}

配置项包括:

  • url:'' 用于请求的url
  • method:'' 创建请求时使用的方法,默认 get
  • baseURL:'' 自动加载url前面,除非url是一个绝对路径
  • transformRequest:[ function(data){return data; } ] 允许在服务器发送前,修改请求数据。
  • transformResponse:[function(data){ return data; }] 在传递给then/catch之前,允许修改响应数据
  • header:{ 'X-Requested-With': 'XMLHttpRequest' } 即将被发送的自定义请求头
  • param:{ ID :12345 } 即将与请求一起发送的url参数
  • paramsSerializer: function(params){ return Qs.stringify(params, {arrayFormat: 'brackets'}) } 负责params序列化的函数
  • data:{ firstName:'' } 作为请求主体被发送的数据,适用于'put' 'post' 'patch'
    • 没有设置transformRequest时,是string, plain object, ArrayBuffer , ArrayBufferView, URLSearchParams
    • 浏览器专属 FromData File Blob
    • Node专属 Stream
  • timeout:1000 指定请求潮湿的毫秒数
  • withCredentials:false 表示跨域请求时是否需要使用凭证 默认的不需要
  • adapter:function(config){}
  • auth:{ } 表示应该使用HTTP基础验证, 并提供凭证
  • responseType:'json' 表示服务器响应的数据类型
  • xsrfCookieName: ' XSRF-TOKEN'
  • onUploadProgress:function(progressEvent){} 允许为上传处理进度事件
  • maxContentLength:2000 允许的响应内容的最大尺寸
  • validateStatus: function(status){ return status} 定义对于给定的HTTP响应状态码是resolve或者reject promise
  • maxRedirects:5 node.js中用于定义在执行http和https时使用的自定义代理
  • httpAgent: new http.Agent({ keepAlive :true })
  • httpsAgent: new https.Agent({ keepAlive:true })
  • proxy:{host:'', port:9000,auth:{}} 定义代理服务器的主机名称和端口 auth表示HTTP基础验证应当用于连接代理,并提供凭证
  • cancelToken: new CancelToken(function(cancel){ }) 指用于取消请求的

node.js标准库中有个querystring,这个库处理url查询字符串
qs 允许根据[]包围的查询字符串来创建嵌套对象
qs npm酷库:是querystring的增强版本,支持内嵌对象和数组

//querystring
const querystring = require('querystring');
querystring.parse('foo=bar&bar=1'); //即{ foo:‘bar’, baz:'1'}
querystring.parse('foo[bar] = 1&baz[]=2') ;//{ ‘foo[bar]’:1, 'baz[]': '2'}  意味着前端表单中存在数组,则标准库无法满足需求
//qs
const qs =  require('qs');
qs.parse('foo[bar] =1&bax[] =2'); //{foo:{ bar :'1'}, baz:['2']}

响应结构

//得到的响应信息
{
  data:{},   由服务器提供的响应
  status:200,  来自服务器响应的HTTP状态码
  statusText: 'OK',   来自服务器响应的HTTP状态信息 
  header:{},  服务器响应头
  config:{} 为请求提供的配置信息
}
//使用方法:
axios.get('/user/1234')
.then(function(response){
  console.log(response.data);
  console.log(response.status);
  console.log(response.statusText);
  console.log(response.header);
  console.log(response.config);
})

默认值/defaults

  • 配置的优先顺序
    • lib/defaults.js 中库的默认值 var instance = axios.create();
    • 实例的defaults属性 instance.defaults.timeout =2500;
    • 请求的config参数 instance.get(url, {timeout:5000})
axios.defaults.baseURL = '';
axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
axios.defaults.headers.post['Content-Type'] ='application/x-www-form-urlencoded';
//自定义实例默认值   并在实例已创建后修改默认值
var instance = axios.create({
  baseURL:'http://...'
})
instance.defaults.headers.common['Authorization'] = AUTH_TOKEN;

拦截器

  • 在请求或者响应被thencatch处理前拦截
  • 请求拦截器axios.interceptors.request.use()
  • 响应拦截器axios.interceptors.reponse.use()
  • 移除拦截器 axios.interceptors.request.eject(拦截器名称)
//请求和响应拦截器
axios.interceptors.request.use(function(config){ 
  //在发送请求之前
  return config;
},function(error){
  //应对请求错误
  return Promise.reject(error)
});
axios.interceptors.response.use(function(){  //在响应数据之前
},function(error){   // 应对响应错误
})
//移除拦截器
var myInterceptor = axios.interceptors.request.use(function () {/*...*/});
axios.interceptors.request.eject(myInterceptor);
//为自定义的axios实例添加拦截器
var instance = axios.create();
instance.interceptors.request.use(...)

Await vs Async

Await

  • async 用于声明一个函数是异步的
  • await是等待异步完成,只能在async函数中使用
  • asyncawait都是跟随Promise一起使用的。
  • async返回的都是一个Promise对象。async适用于任何类型的函数。
  • await得到Promise对象之后就等待Promiseresolvereject
//串行:等待前一个await执行后再执行下一个await
async function asyncAwaitFn(str) {
   return await new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(str)
        }, 1000);
    })
}
const serialFn = async () => { //串行执行
    console.time('serialFn')
    console.log(await asyncAwaitFn('string 1'));
    console.log(await asyncAwaitFn('string 2'));
    console.timeEnd('serialFn')
}
serialFn();
//让多个await并行执行,再执行最后一个await
async function asyncAwaitFn(str) {
    return await new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(str)
        }, 1000);
    })
}
const parallel = async () => { //并行执行
    console.time('parallel')
    const parallelOne = asyncAwaitFn('string 1');
    const parallelTwo = asyncAwaitFn('string 2')
    //直接打印
    console.log(await parallelOne)
    console.log(await parallelTwo)
    console.timeEnd('parallel')
}
parallel()

async/await错误处理

  • async返回的是一个Promise对象,异步请求错误时处理reject的状态。
  • 可以用try....catch
async function catchErr(){
  try{
     const erRes = await new Promise({resolve, reject} => {
          /*.....*/
      });
  }catch(err){  //处理错误情况 }
}

AsyncData

AsyncDara

  • 组件的每次加载之前被调用。加载并渲染
  • 参数是context:上下文对象
export default{
  data(){      return{/*....**/}   },
  asyncData(context){     return {/*....*/}   }
}

Fetch

  • fetch是XMLHttpRequest对象获取后台数据之外的更好的一种替代方案
  • fetch返回一个promise对象
    Axios | Ajax | Await|Async | asyncData | fetch_第1张图片
    浏览器的支持情况
//fetch GET 请求,将参数写在url上 
//带参数的url :'https://www.baidu.com/search/error.html?a=1&b=2'
fetch( url, {  method:'GET'  })
.then(  (res)=>{ return res;   })
.then(  (res)=>{ return res;   })
//fetch POST请求 
//参数指定在fetch第二个参数中
//设置请求头 headers
//强制带cookie ,配置 credentials
fetch( url, {
  method:'POST',  //使用HTTP动词:GET, POST, PUT, DELETE, HEAD
  body: new URLSearchParams([['foo',1],['bar',2]]).toString(), //请求的对象数据
  headers: new Headers({      //关联的Header对象
      'Content-Type' :'application/x-www-form-urlencoded',    // 指定提交方式为表单提交
      ‘Accept’:'application/json' //指定获取数据的类型是JSON
  }),
  credentials:'include',    //是否发送Cookie,强制加入凭据头(omit, same-origin)
  mode: 'cors'   //请求的模式,设置跨域, 得到type:'opaque' 的返回,使用其进行信息上报(cors, no-cors, same-origin)
  integrity:'',  //完整性校验
  cache:'',  //缓存模式  (default, reload, no-cache)
  redirect:''  //收到重定向请求之后的操作 follow, error, manual
})
.then(  (res)=>{ 
      return res.json(); // 返回一个Promise, 可以解析成JSON  
})
.then(  (res)=>{
      console.log(res)  //获取到JSON 数据
})
//fetch封装
/**
 * 将对象转成 a=1&b=2的形式
 * @param obj 对象
 */
function obj2String(obj, arr = [], idx = 0) {
  for (let item in obj) {
    arr[idx++] = [item, obj[item]]
  }
  return new URLSearchParams(arr).toString()
}

/**
 * 真正的请求
 * @param url 请求地址
 * @param options 请求参数
 * @param method 请求方式
 */
function commonFetcdh(url, options, method = 'GET') {
  const searchStr = obj2String(options)
  let initObj = {}
  if (method === 'GET') { // 如果是GET请求,拼接url
    url += '?' + searchStr
    initObj = {
      method: method,
      credentials: 'include'
    }
  } else {
    initObj = {
      method: method,
      credentials: 'include',
      headers: new Headers({
        'Accept': 'application/json',
        'Content-Type': 'application/x-www-form-urlencoded'
      }),
      body: searchStr
    }
  }
  fetch(url, initObj).then((res) => {
    return res.json()
  }).then((res) => {
    return res
  })
}

/**
 * GET请求
 * @param url 请求地址
 * @param options 请求参数
 */
function GET(url, options) {
  return commonFetcdh(url, options, 'GET')
}

/**
 * POST请求
 * @param url 请求地址
 * @param options 请求参数
 */
function POST(url, options) {
  return commonFetcdh(url, options, 'POST')
}

总结:Ajax | Axios | Fetch

Ajax

  • 对原生XHR封装,增添了对JSONP的支持
  • 针对MVC的编程,不符合MVVM
  • 基于原生的XHR开发,已有fetch的替代方案
  • Jquery整个项目太大,单纯使用ajax要引入整个Jquery非常不合理,若个性化打包,则有不能享受CDN服务

Axios

  • 从node.js创建http请求
  • 支持Promise API
  • 客户端支持防止CSRF : 让每个请求都带一个从cookie拿到的key, 根据浏览器同源策略,假冒的网站拿不到key.
  • 提供了一些并发接口
  • 体积比较小

Fetch

  • 符合关注分离,没有将输入,输出和用事件来跟踪的状态混在在一个对象里
  • 更加底层,提供的API丰富
  • 脱离了XHR,ES最新的实现方式
  • 跨域处理,(同源策略,浏览器的请求除非设置跨芋头或借助JSONP,不然不能跨域)

fetch需要填的坑:

  • 只对网络请求报错,对于400,500都当做成功请求
  • 默认不带cookie,需要配置
  • 不支持abort,不支持超时控制。 使用setTimeout及Promise.reject的实现的超时控制并不能阻止请求过程继续在后台运行,造成了流量的浪费
  • fetch不能原生监测请求的进度,而XHR可以

你可能感兴趣的:(Axios | Ajax | Await|Async | asyncData | fetch)