Vue.js 前后端交互模式

一. 前后端交互模式

1.1 接口调用方式

  • 原生 ajax
  • 基于 jQuery 的ajax
  • fetch
  • axios

在这里插入图片描述

1.2 URL 地址格式

1. 传统形式的 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),用于定位页面的某个位置

  • 符合规则的URL

    ①http://www.duanxx.cn

    ②http://www.duanxx.cn/java/web

    ③http://www.duanxx.cn/java/web?flag=1

    ④http://www.duanxx.cn/java/web?flag=1#function

2. Restful 形式的 URL

  • HTTP请求方式

    ① GET 查询

    ② POST 添加

    ③ PUT 修改

    ④ DELETE 删除

  • 符合规则的URL地址

    ① http://www.hello.com/books GET

    ② http://www.hello.com/books POST

    ③ http://www.hello.com/books/123 PUT

    ④ http://www.hello.com/books/123 DELETE

二. Promise 用法

2.1 异步调用

  • 异步效果分析

    ①定时任务

    ②Ajax

    ③事件函数

  • 多次异步调用的依赖分析

    ① 多次异步调用的结果顺序不确定

    ② 异步调用结果如果存在依赖需要嵌套

缺点

形成 回调地狱 。

$.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 是异步编程的一种解决方案,从语法上讲,Promise是一个对象,从它可以获取异步操作的消息。

使用 Promise 主要有以下好处:

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

官方描述:点击这里 ——> Promise

2.3 Promise 基本用法

  • 实例化 Promise 对象,构造函数中传递函数,该函数中用于处理异步任务
  • resolvereject 两个参数用于处理成功和失败两种情况,并通过 p.then 获取处理结果

语法结构

 var p = new Promise(function(resolve, reject){
   // 成功时调用 resolve()
   // 失败时调用 reject()
 });
 p.then(funciton(ret){
     // 从resolve得到正常结果
  }, function(ret){
     // 从reject得到错误信息
  });

案例

<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>promise基本用法</title>
</head>

<body>
    <script type="text/javascript">
        var p = new Promise(function(resolve, reject) {
            // 这里用于实现异步任务
            setTimeout(function() {
                var flag = false;
                if (flag) {
                    // 正常情况
                    resolve("Hello Promise");
                } else {
                    reject('Error ! ! !');
                }
            }, 1000);
        });
        p.then(function(data) {
            console.log(data);
        }, function(info) {
            console.log(info);
        });
    </script>
</body>

</html>

2.4 基于Promise处理Ajax请求

1. 处理原生Ajax

<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Promise处理原生Ajax请求</title>
</head>

<body>
    <script type="text/javascript">
        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('服务器错误!');
                	}
            	};
            	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);
        //     });
        // 多次调用
        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);
            });
    </script>
</body>

</html>

2.5 then参数中的函数返回值

1. 返回 Promise 实例对象

  • 返回的该实例对象会调用下一个 then

2. 返回普通值

  • 返回的普通值会直接传递给下一个 then,通过 then 参数中函数的参数接收该值
  • 如果上一个then返回普通值,它会默认生成一个Promise实例对象,这是为了保证继续链式操作

案例:

<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>then参数中的返回值</title>
</head>

<body>
    <script type="text/javascript">
        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);
            });
        }

        queryData('http://localhost:3000/data')
            .then(function(data) {
                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
                return 'Hello Little Dragon Boy!'
            })
            .then(function(data) {
                console.log(data);
            })
    </script>
</body>

</html>

2.6 Promise常用的API

1. 实例方法

  • p.then() 得到异步任务的正确结果
  • p.catch() 获取异常信息
  • p.finally() 成功与否都会执行(尚且不是正式标准)

案例

<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Promise中常用API</title>
</head>

<body>
    <script type="text/javascript">
        function foo() {
            return new Promise(function(resolve, reject) {
                setTimeout(function() {
                    resolve('Good Promise!');
                    // reject('Error ! ! !');
                }, 100);
            });
        };

        foo()
            .then(function(data) {
                console.log(data);
            })
            .catch(function(data) {
                console.log(data);
            })
            .finally(function() {
                console.log('finished!');
            });
    </script>
</body>

</html>

2. 对象方法

  • Promise.all() 并发处理多个异步任务,所有任务都执行完成才能得到结果
  • Promise.race() 并发处理多个异步任务,只要有一个任务完成就能得到结果
<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>常用API对象方法</title>
</head>

<body>
    <script type="text/javascript">
        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');
        // Promise.all([p1, p2, p3]).then(function(result) {
        //     console.log(result);
        // });
        Promise.race([p1, p2, p3]).then(function(result) {
            console.log(result);
        });
    </script>
</body>

</html>

三. 接口调用-fetch用法

3.1 fetch 概述

1. 基本特性

  • 更加简单的数据获取方式,功能更强大、更灵活,可以看做是xhr的升级版
  • 基于Promise实现

2. 语法结构

  fetch(url).then(fn2)
            .then(fn3)
            ...
            .catch(fn)

官方描述:点击这里 ——> Fetch API

3.2 fetch 的基本用法

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

3.3 fetch请求参数

1. 常用配置选项

  • method(String): HTTP请求方法,默认为GET (GET、POST、PUT、DELETE)
  • body(String): HTTP的请求参数
  • headers(Object): HTTP的请求头,默认为{}

2. GET请求方式的参数传递

// 方法1
fetch('http://localhost:3000/books?id=123', {
		method: 'get',
	}).then(function(data) {
		return data.text();
	}).then(function(data) {
		console.log(data);
	});
// ---------------------------------------------
app.get('/books', (req, res) => {
    res.send('传统 url 参数传递!' + req.query.id);
});
// 方法2
fetch('http://localhost:3000/books/456', {
		method: 'get',
	}).then(function(data) {
		return data.text();
	}).then(function(data) {
		console.log(data);
	});
// ---------------------------------------------
app.get('/books/:id', (req, res) => {
    res.send('Restful 形式的 url 传递参数!' + req.params.id)
});

3. DELETE请求方式的参数传递

另一种方法同上。

fetch('http://localhost:3000/books/789', {
		method: 'delete',
	}).then(function(data) {
		return data.text();
   	}).then(function(data) {
    	console.log(data);
    });
// ---------------------------------------------
app.delete('/books/:id', (req, res) => {
    res.send('delete 传递参数!' + req.params.id);
});

4 POST请求方式的参数传递

fetch('http://localhost:3000/books/987', {
         method: 'put',
         body: 'uname=段仙子&pwd=123',
         headers: {
              'Content-Type': 'application/x-www-form-urlencoded'
         }
     }).then(function(data) {
         return data.text();
     }).then(function(data) {
         console.log(data);
     });
// ---------------------------------------------
app.post('/books', (req, res) => {
    res.send('post 传递参数!' + req.body.uname + '----' + req.body.pwd);
});

5. PUT请求方式的参数传递

fetch('http://localhost:3000/books/987', {
         method: 'put',
         body: JSON.stringify({
             uname: '段仙子',
             pwd: '20',
         }),
         headers: {
             'Content-Type': 'application/json'
         }
     }).then(function(data) {
         return data.text();
     }).then(function(data) {
         console.log(data);
     });
// ---------------------------------------------
app.put('/books/:id', (req, res) => {
    res.send('put 传递参数!' + req.params.id + '----' + req.body.uname + '----' + req.body.pwd);
});

3.4 fetch响应结果

响应数据格式

  • text(): 将返回体处理成字符串类型
  • json():返回结果和 JSON.parse(responseText)一样
	fetch('http://localhost:3000/json', {
	    method: 'get',
	}).then(function(data) {
	    return data.json();
	}).then(function(data) {
	    console.log(data);
	})

//-----------------------------------------------------

	fetch('http://localhost:3000/json', {
		method: 'get',
	}).then(function(data) {
		return data.text();
	}).then(function(data) {
		console.log(data);
	})

在这里插入图片描述

在这里插入图片描述

四. 接口调用-axios用法

4.1 axios 的基本特性

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

它具有以下特征:

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

4.2 axios 的基本用法

<body>
    <script src="./js/axios.js"></script>
    <script type="text/javascript">
        axios.get('http://localhost:3000/adata').then(function(ret) {
            console.log(ret);
            // data 属性是固定用法,用于获取后台的实际数据。
            // console.log(ret.data);
        })
    </script>
</body>

4.3 axios 的常用API

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

4.4 axios 的参数传递

1. GET传递参数

  • 通过 URL 传递参数

    axios.get('http://localhost:3000/axios?id=111').then(function(ret) {
    	console.log(ret.data);
    });
    
    axios.get('http://localhost:3000/axios/222').then(function(ret) {
    	console.log(ret.data);
    });
    
  • 通过 params 选项传递参数

    // 在前端中,如果使用parms传参,后台获取参数的方法要用 req.query
    // parms 是 axios专门提供的。
    axios.get('http://localhost:3000/axios', {
    	params: {
    		id: 999
    	}
    }).then(function(ret) {
    	console.log(ret.data);
    });
    

2. DELETE传递参数

  • 通过 URL 传递参数

    axios.delete('http://localhost:3000/axios?id=111').then(function(ret) {
    	console.log(ret.data);
    });
    
    axios.delete('http://localhost:3000/axios/222').then(function(ret) {
    	console.log(ret.data);
    });
    
  • 通过 params 选项传递参数\

    axios.delete('http://localhost:3000/axios', {
    	params: {
    		id: 123
    	}
    }).then(function(ret) {
    	console.log(ret.data);
    });
    

3. POST传递参数

  • 通过选项传递参数(默认传递的是 json 格式的数据)

    axios.post('http://localhost:3000/axios', {
    	uname: '段仙子',
    	age: 18
    }).then(function(ret) {
    	console.log(ret.data);
    });
    
  • 通过 URLSearchParams 传递参数(application/x-www-form-urlencoded)

    const params = new URLSearchParams();
    params.append('uname', '段小小');
    params.append('age', '20');
    axios.post('http://localhost:3000/axios', params).then(function(ret) {
    	console.log(ret.data);
    });
    

4. PUT传递参数

  • 通过选项传递参数(默认传递的是 json 格式的数据)

    axios.put('http://localhost:3000/axios', {
    	uname: '段仙子',
    	age: 99
    }).then(function(ret) {
    	console.log(ret.data);
    });
    
  • 通过 URLSearchParams 传递参数(application/x-www-form-urlencoded)

    const params = new URLSearchParams();
    params.append('uname', '小小段');
    params.append('age', '21');
    axios.put('http://localhost:3000/axios', params).then(function(ret) {
    	console.log(ret.data);
    });
    

4.5 axios 的响应结果

响应结果的主要属性

  • data : 实际响应回来的数据
  • headers :响应头信息
  • status :响应状态码
  • statusText :响应状态信息

在这里插入图片描述

4.6 axios 的全局配置

<body>
    <script src="./js/axios.js"></script>
    <script type="text/javascript">
        // 超时时间
        axios.defaults.timeout = 3000;
        // 配置请求的基准 URL 地址
        axios.defaults.baseURL = 'http://localhost:3000';
        // 设置请求头
        axios.defaults.headers['mytoken'] = 'duanxiaoxioa ^_^';
        axios.get('/axios-json').then(function(ret) {
            console.log(ret.data.uname);
        })
    </script>
</body>

4.7 axios拦截器

1. 请求拦截器

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

在这里插入图片描述

2. 响应拦截器

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

在这里插入图片描述

<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>请求拦截器</title>
</head>

<body>
    <script src="./js/axios.js"></script>
    <script type="text/javascript">
        axios.defaults.baseURL = 'http://localhost:3000';
        // 请求拦截器
        axios.interceptors.request.use(function(config) {
            //在请求发出之前进行一些信息设置
            console.log(config.url);
            config.headers['mytoken'] = 'good!';
            return config
        }, function(err) {
            // 处理响应的错误信息
            console.log(err);
        });

        // 相应拦截器
        axios.interceptors.response.use(function(res) {
            //在这里对返回的数据进行处理
            // console.log(res)
            var data = res.data;
            return data;
        }, function(err) {
            // 处理响应的错误信息
            console.log(err);
        });

        axios.get('/adata').then(res => {
            console.log(res);
        })
    </script>
</body>

</html>

在这里插入图片描述

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

5.1 async/await 的基本用法

  • async/await是ES7引入的新语法,可以更加方便的进行异步操作
  • async 关键字用于函数上(async函数的返回值是Promise实例对象)
  • await 关键字用于 async 函数当中(await可以得到异步的结果)
	<script type="text/javascript">
        axios.defaults.baseURL = 'http://localhost:3000';
        // async function queryDate() {
        //     var res = await axios.get('/adata');
        //     // 1. console.log(res.data);
        //     return res.data;
        // };
        // // 1. queryDate();
        // queryDate().then(res => {
        //     console.log(res);
        // });

        // 模拟异步
        async function queryDate() {
            var res = await new Promise(function(resolve, reject) {
                setTimeout(function() {
                    resolve('nihao');
                }, 1000);
            })
            return res;
        };

        queryDate().then(date => {
            console.log(date);
        });
    </script>

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

	<script type="text/javascript">
        axios.defaults.baseURL = "http://localhost:3000";
        async function queryDate() {
            var info = await axios.get("async1");
            var ret = await axios.get("async2?info=" + info.data);
            return ret.data;
        };

        queryDate().then(data => {
            console.log(data);
        })
    </script>

    <!-- 接口 -->
	// async-await
	app.get('/async1', (req, res) => {
    	res.send('Hello1');
	});

	app.get('/async2', (req, res) => {
    	if (req.query.info == 'Hello') {
        	res.send('Hello Async-Await!');
    	} else {
        	res.send('Error');
    	}
	});
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值