Axios | Ajax | Await|Async | asyncData | fetch

Axios vs Ajax

Axios

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

安装

  • npm install axois
  • <script src='https://unpkg.com/axios/dist/axios.min.js'></script>

使用: 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对象
    浏览器的支持情况
//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可以
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,100评论 18 139
  • ## 框架和库的区别?> 框架(framework):一套完整的软件设计架构和**解决方案**。> > 库(lib...
    Rui_bdad阅读 2,855评论 1 4
  • 原文连接:https://blog.csdn.net/sinat_17775997/article/details...
    小豆soybean阅读 4,198评论 0 7
  • Vue.js 1.0 我们常使用 vue-resource (官方ajax库), Vue 2.0 发布后作者宣告不...
    九四年的风阅读 23,790评论 1 8
  • 异步编程对JavaScript语言太重要。Javascript语言的执行环境是“单线程”的,如果没有异步编程,根本...
    呼呼哥阅读 7,254评论 5 22