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
- 没有设置transformRequest时,是
-
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;
拦截器
- 在请求或者响应被
then
或catch
处理前拦截 -
请求拦截器
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函数中使用
- async和 await都是跟随Promise一起使用的。
- async返回的都是一个Promise对象。async适用于任何类型的函数。
- await得到Promise对象之后就等待Promise的resolve或reject
//串行:等待前一个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可以