Vue - 前后端交互

1. 前后端交互模式

1.1 接口调用方式

  • 原生Ajax
  • 基于JQuery的Ajax
  • fetch
  • axios

1.2 URL地址

1.2.1 传统形式的URL
  • 格式:schema://host:post/path?query#fragment
    1. schema:协议
    2. host:域名或IP地址
    3. port:端口,http默认端口80,可省略
    4. path:路径
    5. query:查询参数
    6. fragment:锚点(哈希Hash),用于定位页面的某个位置
1.2.2 restful形式的URL
  • HTTP请求方式

    1. GET 查询
    2. POST 添加
    3. PUT 修改
    4. DELETE 删除
  • 符合规则的URL地址

    1. http://www.hello.com/books GET
    2. http://www.hello.com/books POST
    3. http://www.hello.com/books /123 PUT
    4. http://www.hello.com/books /123 DELETE

2. Promise 用法

2.1 异步调用

  • 异步效果分析
    1. 定时任务
    2. Ajax
    3. 事件函数

2.2 概述

异步编程的一种解决方案。从语法上讲,Promise是一个对象,从它可以获取异步操作的消息。

好处:

  • 可以避免多层异步调用嵌套问题(回调地狱)
  • Promise对象提供了简洁的API,使得控制异步操作更加容易

2.3 用法

  • 实例化Promise对象,构造函数中传递函数,该函数中用于处理异步任务。
  • resolve 和 reject 两个参数用于处理成功和失败两种情况,并通过p.then获取处理结果。
var p = new Promise(function(resolve, reject) {
	// 成功时调用 resolve() 
	// 失败时调用 reject()
});
p.then(function(ret) {
	// 从resolve得到正常结果
}, function(ret) {
	// 从reject得到错误信息
});

2.4 基于Promise处理Ajax请求

2.4.1 处理原生Ajax
<script>
        function queryData(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('error')
                    }
                };
                xhr.open('get', url);
                xhr.send(null);
            });
            return p;
        }
        queryData('http://localhost:3000/data')
            .then(function(data) {
                console.log(data);
            }, function(info) {
                console.log(info);
            });
    </script>
2.4.2 发送多次Ajax请求
queryData() 
.then(function(data) {
	return queryData();
})
.then(function(data) {
	return queryData();
})
.then(function(data) {
	return queryData();
});
// 发送多个Ajax请求,并保证顺序
        queryData('http://localhost:3000/data')
            .then(function(data) {
                console.log(data);
                return queryData('http://localhost:3000/data1');
            })
            .then(function(data) {
                console.log(data);
                return queryData('http://localhost:3000/data2');
            })
            .then(function(data) {
                console.log(data);
            })

2.5 then参数中的函数返回值

2.5.1 返回promise实例对象
  • 返回的该实例对象会调用下一个then
2.5.2 返回普通值
  • 返回的普通值会直接传递给下一个then,通过then参数中函数的参数接收该值
queryData('http://localhost:3000/data')
            .then(function(data) {
                return queryData('http://localhost:3000/data1');
            })
            .then(function(data) {
                return new Promise(function(resolve, reject) {
                    setTimeout(function() {
                        resolve(123);
                    }, 1000)
                });
            })
            .then(function(data) {
                console.log(data);   //123
            })
queryData('http://localhost:3000/data')
            .then(function(data) {
                return queryData('http://localhost:3000/data1');
            })
            .then(function(data) {
                return new Promise(function(resolve, reject) {
                    setTimeout(function() {
                        resolve(123);
                    }, 1000)
                });
            })
            .then(function(data) {
                return 'hello';
            })
            .then(function(data) {
                console.log(data);   // hello
            })

2.6 Promise常用API

2.6.1 实例方法
  • p.then() 得到异步任务的正确结果
  • p.catch() 获取异常信息
  • p.finally() 成功与否都会执行
queryData()
	.then(function(data) {
		console.log(data);
	})
	.catch(function(data) {
		console.log(data);
	})
	.finally(function(data) {
		console.log('finished');
	})

例子:

    <script>
        // console.dir(Promise)
        function foo() {
            return new Promise(function(resolve, reject) {
                setTimeout(function() {
                    // resolve(123);
                    reject('error')
                }, 100)
            })
        }
        // foo()
        //     .then(function(data) {
        //         console.log(data);
        //     })
        //     .catch(function(data) {
        //         console.log(data);
        //     })
        //     .finally(function() {
        //         console.log('finished');
        //     });



        // 与上面写法等效,但是用catch语义比较清晰
        foo()
            .then(function(data) {
                console.log(data);
            }, function(data) {
                console.log(data);
            })
            .finally(function() {
                console.log('finished');
            });
    </script>

在这里插入图片描述

2.6.2 对象方法
  • Promise.all() 并发处理多个异步任务,所有任务都执行完成才能得到结果
  • Promise.race() 并发处理多个任务,只要有一个任务完成就能得到结果
Promise.all([p1, p2, p3]).then((result) => {
	console.log(result)
})
Promise.race([p1, p2, p3]).then((result) => {
	console.log(result)
})

例子:

app.get('/a1', (req, res) => {
    setTimeout(function() {
        res.send('Hello')
    }, 1000)
});
app.get('/a2', (req, res) => {
    setTimeout(function() {
        res.send('World')
    }, 2000)
});
app.get('/a3', (req, res) => {
    setTimeout(function() {
        res.send('Hello World!')
    }, 3000)
});
   <script>
        // console.dir(Promise)
        function queryData(url) {
            return 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);
            });
        }

        var p1 = queryData('http://localhost:3000/a1');
        var p2 = queryData('http://localhost:3000/a2');
        var p3 = queryData('http://localhost:3000/a3');

        // 拿到三个结果  ["Hello", "World", "Hello World!"]
        Promise.all([p1, p2, p3]).then(function(result) {
            console.log(result);
        })

        // 只拿到第一个结果  hello
        Promise.race([p1, p2, p3]).then(function(result) {
            console.log(result);
        })
    </script>

3. 接口调用-fetch用法

3.1 fetch概述

3.1.1 基本特性
  • 更加简单的数据获取方式,功能更强大、更灵活,可以看作是xhr的升级版
  • 基于Promise实现
3.1.2 语法结构
fetch(url).then(fn2)
		  .then(fn3)
		  ...
		  .then(fn)

3.2 fetch基本用法

fetch('/abc').then(data => {
	// text() 方法属于fetchAPI的一部分,他返回一个Promise实例对象,用于获取后台返回数据
	return data.text();
}).then(ret => {
	// 注意这里得到的才是最终数据
	console.log(ret);
});

3.3 fetch请求参数

3.3.1 常用配置选项
  • method(String):HTTP请求方法,默认为GET(GET、POST、PUT、DELETE)
  • body(String):HTTP的请求参数
  • headers(Object):HTTP的请求头,默认为{}
fetch('/abc'), {
	methods: 'get'
}).then(data => {
	return data.text();
}).then(ret => {
	// 注意这里得到的才是最终数据
	console.log(ret);
});
3.3.2 GET请求方式的参数传递

第一种:

fetch('/abc?id=123').then(data => {
	return data.text();
}).then(ret => {
	// 注意这里得到的才是最终数据
	console.log(ret);
});

第二种:

fetch('/abc/123', {
	method: 'get'
}).then(data => {
	return data.text();
}).then(ret => {
	// 注意这里得到的才是最终数据
	console.log(ret);
});

例子:

app.get('/books', (req, res) => {
    res.send('传统的URL传递参数' + req.query.id)
});
app.get('/books/:id', (req, res) => {
    res.send('Restful形式的URL传递参数' + req.params.id)
});


    <script>
        // fetch('http://localhost:3000/books?id=123', {
        //         method: 'get'
        //     })
        //     .then(function(data) {
        //         return data.text();
        //     }).then(function(data) {
        //         console.log(data);
        //     });

        fetch('http://localhost:3000/books/456', {
                method: 'get'
            })
            .then(function(data) {
                return data.text();
            }).then(function(data) {
                console.log(data);
            });
    </script>

在这里插入图片描述

3.3.3 DELETE请求方式的参数传递
fetch('/abc/123', {
	method: 'delete'
}).then(data => {
	return data.text();
}).then(ret => {
	// 注意这里得到的才是最终数据
	console.log(ret);
});
3.3.4 POST请求方式的参数传递

方法一:

fetch('/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);
});

方法二:

fetch('/books', {
	method: 'post',
	body: JSON.stringify({
		uname: 'lisi',
		age: 12
	}),
	headers: {
		'Content-Type': 'application/json',
	}
}).then(data => {
	return data.text();
}).then(ret => {
	console.log(ret);
});
3.3.5 PUT请求方式的参数传递
fetch('/books/123', {
	method: 'put',
	body: JSON.stringify({
		uname: 'lisi',
		age: 12
	}),
	headers: {
		'Content-Type': 'application/json',
	}
}).then(data => {
	return data.text();
}).then(ret => {
	console.log(ret);
});

3.4 fetch响应结果

相应数据格式
  • text() :将返回处理成字符串类型
  • json() :返回结果和JSON.prase(reponse Text)一样
fetch('/abc' then(data => {
	// return data.text();
	return data.json();
}).then(ret => {
	console.log(ret);
});

4. 接口调用-axios用法

4.1 基本特性

axios是一个基于Promise用于浏览器和node.js的HTTP客户端

特性:

  • 支持浏览器和node.js
  • 支持promise
  • 能拦截请求和响应
  • 自动转换JSON数据

4.2 基本用法

axios.get('/adata')
	.then(ret => {
		// data属性名称是固定的,用于获取后台响应的数据
		console.log(ret.data)
	})

4.3 axios常用API

  • get:查询数据
  • post:添加数据
  • put:修改数据
  • delete:删除数据

4.4 axios的参数传递

4.4.1 GET传递参数
  • 通过URL传递参数
axios.get('/adata?id=123')
	.then(ret => {
		console.log(ret.data)
	})
  • 通过Params选项传递参数
axios.get('/adata/123')
	.then(ret => {
		console.log(ret.data)
	})
axios.get('/adata', {
	params: {
		id: 123
		}
	})
	.then(ret => {
		console.log(ret.data);
	})
4.4.2 DELETE传递参数
  • 传参方式与GET类似
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.3 POST传递参数
  • 通过选项传递参数(默认传递的是json格式的数据)
axios.post('/adata', {
	uname: 'tom',
	pwd; 123
}).then(ret => {
	console.log(ret.data)
})
  • 通过URLSearchParams传递参数(application/x-www-form-urlencoded)
const params = new URLSearchParams();
params.append('param1', 'value1');
params.append('param2', 'value2');
axios.post('api/test', params).then(ret => {
	consloe.log(ret.data)
})
4.4.4 PUT传递参数
  • 参数传递与POST类似
axios.put('/adata/123', {
	uname: 'tom',
	pwd; 123
}).then(ret => {
	console.log(ret.data)
})

4.5 axios响应结果

响应结果的主要属性
  • data: 实际响应回来的数据
  • headers:响应头信息
  • status:响应状态码
  • statusText:响应状态信息
axios.post('/axios-json').then(ret => {
	console.log(ret)
})

4.6 axios的全局配置

  • axios.dafaults.timeout = 3000; // 超时时间
  • axios.defaults.baseURL = ‘http://localhost:3000/app’; // 默认地址
  • axios.defaults.headers[‘mytoken’] = ‘fhtwjhnb564ts36n’ // 设置请求头

4.7 axios拦截器

4.7.1 请求拦截器

在请求发出之前设置一些信息

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

在获取数据之前对数据做一些加工处理

// 添加一个响应拦截器
axios.interceptors.response.use(function(res) {
	// 在这里对返回的数据进行处理
	return res;
}, function(err) {
	// 处理响应的错误信息
};

5. 接口调用-async/await用法

5.1 async/await 的基本用法

  • async/await是ES7引入的新语法,可以更加方便的进行异步操作
  • async关键字用于函数上,(async函数的返回值是Promise实例对象)
  • await关键字用于async函数当中(await可以得到异步的结果)
async function queryData(id) {
	const ret = await axios.get('/data');
	return ret;
}
queryData.then(ret => {
	console.log(ret)
})

5.2 async/await 处理多个异步请求

多个异步请求的场景

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)
})
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值