1 基础概念
1.1 接口调用的方式
- 原生 ajax 
- 基于 jQuery 的ajax 
- fetch 
- axios
1.2 URL格式
格式:schema://host:port/path?query#fragment 
① schema:协议。例如http、https、ftp等 
② host:域名或者IP地址 
③ port:端口, http默认端口80,可以省略 
④ path:路径, 例如/abc/a/b/c 
⑤ query :查询参数,例如 uname=lisi&age=12 
⑥ fragment :锚点(哈希Hash),用于定位页面的某个位置
Restful: http://www.hello.com/books/123
1.3 http请求方式
① GET 查询
② POST 添加
③ PUT 修改
④ DELETE 删除  
2 异步解决方案 Promise
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
异步:
① 定时任务 
② Ajax 
③ 事件函数
2.1 传统多次异步调用依赖产生问题—回调地狱
异步调用结果如果存在依赖需要嵌套,依赖就是需要顺序输出。
$.ajax({
success: function (data) {
if (data.status == 200) {
$.ajax({
success: function (data) {
if (data.status == 200) {
$.ajax({
success: function (data) {
if (data.status == 200) { }
}
});
}
}
});
}
}
});
2.2 Promise基本用法
Promise 是异步编程的一种解决方案。
类型是函数。也是一个对象,可以获取异步操作的消息。
它提供了简洁的API,使得控制异步操作更加容易。
- resolve 和 reject 两个参数用于处理成功和失败两种情况,
- 当异步任务顺利完成且返回结果值时,会调用 resolve 函数;而当异步任务失败且返回失败原因(通常是一个错误对象)时,会调用reject 函数,并通过 p.then 获取处理结果
 案例: ```javascript var p = new Promise(function (resolve, reject) { setTimeout(function () { var flag = true; flag ? resolve(‘nice’) : reject(‘err,hehehe’) }) });- var p = new Promise(function(resolve, reject){
- // 成功时调用 resolve()
- // 失败时调用 reject()
- });
- p.then(function(ret){
- // 从resolve得到正常结果
- }, function(ret){
- // 从reject得到错误信息
- });
 
p.then(ok => { console.log(ok) }, err => { console.log(err) })

<a name="vHRDd"></a>
## 2.3 封装ajax,发送多个请求
单次调用
```javascript
function queryDate(url) {
var p = new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState != 4) return;
if (xhr.readyState == 4 && xhr.status == 200) {
resolve(xhr.responseText);
} else {
reject('服务器异常');
}
}
xhr.open('get', url);
xhr.send(null);
})
return p
}
queryDate('http://localhost:3000/data')
.then(function (data) {
console.log(data);
}, function (info) {
console.log(info);
})
多次调用:
queryDate('http://localhost:3000/data')
.then(function (data) {
console.log(data);
return queryDate('http://localhost:3000/data1');
}).then(function (data) {
console.log(data);
return queryDate('http://localhost:3000/data2');
}).then(function (data) {
console.log(data);
})

通过返回Promise实例对象,调用下一个then,变成链式从而解决回调地狱。
2.4 then参数的函数返回值
若是返回一个普通值,这个也会产生一个默认的Promise对象继续可以使用then,通过 then 参数中函数的参数接收该值。
queryDate('http://localhost:3000/data')
.then(function (data) {
console.log(data);
return "helloworld";
}).then(data => {
console.log(data);
})
2.5 Promise实例方法
- p.then() 得到异步任务的正确结果 
- p.catch() 获取异常信息 
- p.finally() 成功与否都会执行(尚且不是正式标准)
function foo() {
return new Promise(function(resolve, reject) {
setTimeout(function(){
reject('err')
}, 100);
});
}
foo().then(data => {
console.log(data);
}).catch( err=>{
console.log(err);
}).finally(function() {
console.log('finish end');
})

foo().then(data => {
console.log(data);
}).catch( err=>{
console.log(err);
})
等价于
foo().then(data => {
console.log(data);
},err=>{
console.log(err);
})
2.6 Promise对象方法
- Promise.all() 并发处理多个异步任务,所有任务都执行完成才能得到结果 
- Promise.race() 并发处理多个异步任务,只要有一个任务完成就能得到结果
```javascript
function queryDate(url) {
var p = new Promise(function (resolve, reject) {
  var xhr = new XMLHttpRequest();
  xhr.onreadystatechange = function () {
 } xhr.open(‘get’, url); xhr.send(null); }) return p; }- if (xhr.readyState != 4) return;
- if (xhr.readyState == 4 && xhr.status == 200) {
- resolve(xhr.responseText);
- } else {
- reject('服务器异常');
- }
 
var p1 = queryDate(‘http://localhost:3000/a1‘); var p2 = queryDate(‘http://localhost:3000/a2‘); var p3 = queryDate(‘http://localhost:3000/a3‘); Promise.all([p1, p2, p3]).then(result => { console.log(result); }); Promise.race([p1, p2, p3]).then(result => { console.log(result); });

<a name="XrNQl"></a>
# 3 fetch
[https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API)<br />更加简单的数据获取方式,功能更强大、更灵活,可以看做是xhr的升级版<br />基于Promise实现
<a name="YpY5d"></a>
## 3.1 基本使用
常用配置选项 
- method(String): HTTP请求方法,默认为GET (GET、POST、PUT、DELETE) 
- body(String): HTTP的请求参数 
- headers(Object): HTTP的请求头,默认为{}
默认请求方式是get
```javascript
fetch('http://localhost:3000/fdata').then(function(data){
console.log(data);
// text()方法属于fetchAPI一部分,返回一个Promise实例对象,用于获取后台返回数据
return data.text();
}).then(function(data){
// 注意这里得到的才是最终的数据
console.log(data);
});

3.2 delete请求方式
fetch('/abc/123', {
method: 'delete'
}).then(data => {
return data.text();
}).then(ret => {
// 注意这里得到的才是最终的数据
console.log(ret);
});
3.3 post请求方式
fetch('http://localhost:3000/books', {
method: 'post',
body: 'uname=lisi&pwd=123',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
}
}).then(data => {
return data.text();
}).then(ret => {
console.log(ret);
});
3.4 put请求方式
fetch('http://localhost:3000/books/123', {
method: 'PUT',
body: JSON.stringify({
uname: '张三',
pwd: '789'
}),
headers: {
'Content-Type': 'application/json'
}
})
.then(function(data){
return data.text();
}).then(function(data){
console.log(data)
});
3.5 返回JSON格式数据
响应数据格式 
- text(): 将返回体处理成字符串类型 
- json():返回结果和 JSON.parse(responseText)一样- fetch('/abc' then(data=>{
- // return data.text();
- return data.json();
- }).then(ret=>{
- console.log(ret);
- });
 
4 axios
它的底层也是封装xhr
axios(官网:https://github.com/axios/axios)
是一个基于Promise 用于浏览器和 node.js 的 HTTP 客户端。
- 支持浏览器和 node.js 
- 支持 promise 
- 能拦截请求和响应 
- 自动转换 JSON 数据
4.1 基本用法data属性名称是固定的,用于获取后台响应的数据- axios.get('http://localhost:3000/adata').then(el => {
- console.log(el.data);
- })
   4.2 get带参数请求```javascript axios.get(‘/adata?id=123’).then(ret=>{
 })- console.log(ret.data)
 
axios.get(‘/adata/123’).then(ret=>{ console.log(ret.data) })
axios.get(‘/adata’,{ params: { id: 123 } }).then(ret=>{ console.log(ret.data) })
<a name="03KfE"></a>
## 4.3 delete
```javascript
axios.delete('/adata?id=123').then(ret=>{
console.log(ret.data)
});
axios.delete('/adata/123').then(ret=>{
console.log(ret.data)
});
axios.delete(‘/adata‘,{params: {id: 123}}).then(ret=>{
console.log(ret.data)
})
4.4 post
默认传递的是 json 格式的数据
axios.post('/adata',{
uname: 'tom',
pwd: 123
}).then(ret=>{
console.log(ret.data)
})
通过 URLSearchParams 传递参数(application/x-www-form-urlencoded)**URLSearchParams** 接口定义了一些实用的方法来处理 URL 的查询字符串[URLSearchParams.append()](https://developer.mozilla.org/zh-CN/docs/Web/API/URLSearchParams/append)插入一个指定的键/值对作为新的搜索参数。
const params = new URLSearchParams();
params.append('param1', 'value1');
params.append('param2', 'value2');
axios.post('/api/test', params).then(ret=>{
console.log(ret.data)
})
4.5 put
axios.put(‘/adata/123',{
uname: 'tom',
pwd: 123
}).then(ret=>{
console.log(ret.data)
})
4.6 axios 的响应结果
响应结果的主要属性 
- data : 实际响应回来的数据 
- headers :响应头信息 
- status :响应状态码 
- statusText :响应状态信息- axios.post('/axios-json').then(ret=>{
- console.log(ret)
- })
  
4.7 全局配置
axios.defaults.timeout = 3000; // 超时时间
axios.defaults.baseURL = 'http://localhost:3000/app'; // 默认地址
axios.defaults.headers['mytoken'] = 'aqwerwqwerqwer2ewrwe23eresdf23’// 设置请求头
4.8 axios拦截器请求拦截器

//添加一个请求拦截器
axios.interceptors.request.use(function(config){
//在请求发出之前进行一些信息设置
return config;
},function(err){
// 处理响应的错误信息
});
4.9 响应拦截器

//添加一个响应拦截器
axios.interceptors.response.use(function(res){
//在这里对返回的数据进行处理
return res;
},function(err){
// 处理响应的错误信息
})
案例:
axios.interceptors.request.use(function(config) {
console.log(config.url)
config.headers.mytoken = 'nihao';
return config;
}, function(err){
console.log(err)
})
axios.interceptors.response.use(function(res) {
var data = res.data;
return data;
}, function(err){
console.log(err)
})
axios.get('http://localhost:3000/adata').then(function(data){
console.log(data)
})
5 async/await
- async/await是ES7引入的新语法,可以更加方便的进行异步操作 
- async 关键字用于函数上(async函数的返回值是Promise实例对象) 
- await 关键字用于 async 函数当中(await可以得到异步的结果) - 5.1 基本使用- async function queryData(id) {
- const ret = await axios.get('/data');
- return ret;
- }
- queryData.then(ret=>{
- console.log(ret)
- })
 - 使用案例: - deleteBook: async function (i) {
- var val = await axios.delete('books/' + i);
- val.status == 200 && this.queryDate();
- },
 
- 因为async函数的返回值是Promise实例对象 
- await 右侧的表达式一般为 promise 对象
- await 返回的是 promise 成功的值
- await 的 promise 失败了, 就会抛出异常, 需要通过 try…catch 捕获处理
5.2 多个异步请求
async function queryData(id) {
const info = await axios.get('/async1');
const ret = await axios.get(‘async2?info=‘+info.data);
return ret;
}
queryData.then(ret=>{
console.log(ret)
})
5.3 使用then和不使用then
两个console.log()值都一样
async function getList() {
var url = 'http://www.liulongbin.top:3006/api/get'
// 请求的参数对象
var paramsObj = { name: 'zs', age: 20 }
const result = await axios.get(url, { params: paramsObj })
console.log(result);
return result
}
getList().then(ret => {
console.log(ret)
})

 

 
 
                         
                                

