前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >都0202年了,你还不会前后端交互吗

都0202年了,你还不会前后端交互吗

作者头像
Gorit
发布2021-12-08 21:39:41
1.8K0
发布2021-12-08 21:39:41
举报

文章目录

出了点小 bug, 为啥后面的 post 请求, Flask 都接收不到

一、后端 API 服务搭建

为了方便我采用 Python Flask 编写 API,如果有其他 api 服务搭建的同学,可以移步:四种方式搭建 API,总有一款适合你

编写 Flask 程序应用框架

代码语言:javascript
复制
#!/usr/bin/python
# -*- coding: utf-8 --
#@File: app.py
#@author: Gorit
#@contact: gorit@qq.com
#@time: 2020/5/9 11:58

from flask import Flask, request
app = Flask(__name__)

# 解决跨域问题
@app.after_request
def cors(environ):
    environ.headers['Access-Control-Allow-Origin']='*'
    environ.headers['Access-Control-Allow-Method']='*'
    environ.headers['Access-Control-Allow-Headers']='x-requested-with,content-type'
    return environ

@app.route("/data")
def data():
    return "Hello World"

if __name__ == '__main__':
    app.run(port=3000,debug=True)

项目成功 跑起来了

二、原生 ajax

原生的 ajax 是基于 XMLhttpRequest 进行数据传输的,关于什么是 ajax,可以看这两篇解释,以及基本使用

原生 ajax 实现 (这个调试花了我好久时间)

原生 ajax + Java EE 实现用户验证功能

原生 ajax + Java EE 实现二级菜单联动

原生的 ajax 代码量过长,我在这里就不在演示了,这里我使用 Jquery 完成原生的 ajax 操作

2.1 不带参数的 get 请求

后端接口编写

代码语言:javascript
复制
# 解决跨域请求问题,后面就不带这个了
@app.after_request
def cors(environ):
    environ.headers['Access-Control-Allow-Origin']='*'
    environ.headers['Access-Control-Allow-Method']='*'
    environ.headers['Access-Control-Allow-Headers']='x-requested-with,content-type'
    return environ

# 不带参数的 get 请求
@app.route("/ajax/data")
def ajax():
    return '我收到了 ajax 的请求'

前端 js

代码语言:javascript
复制
	<script>
		// get 请求
		$.ajax({
			url: "http://127.0.0.1:3000/ajax/data",
			type: "get",
			success: function(msg) {
				console.log(msg);
			}
		})
	</script>

成功响应

2.2 带参数的 get 请求

后端接口编写

代码语言:javascript
复制
# 带参数的 get 请求
@app.route("/ajax/data1")
def ajax1():
    # Flask 获取 get 请求参数的方式
    uname = request.args.get("uname")
    pwd = request.args.get("pwd")
    print(uname,pwd)
    return f"get 请求的参数:uname:{uname}, pwd:{pwd}"

后端响应

前端 js

代码语言:javascript
复制
	// 带参数的 get 请求
	$.ajax({
		url: "http://127.0.0.1:3000/ajax/data1",
		type: "get",
		data: {
			"uname": "cici",
			"pwd":123456
		},
		success: function(msg) {
			console.log(msg);
		}
	})

前端响应结果

2.3 带参数的 post 请求

后端 API 编写

代码语言:javascript
复制
@app.route("/ajax/post",methods=['POST'])
def post():
    # Flask 获取 post 参数
    uname = request.form.get("uname")
    pwd = request.form.get("pwd")
    print(uname,pwd)
    return f"post 请求的参数:uname:{uname}, pwd:{pwd}"

后端响应

前端 js

代码语言:javascript
复制
	// 带参数的 post 请求
	$.ajax({
		url: "http://127.0.0.1:3000/ajax/post",
		type: "post",
		data: {
			"uname": "cici",
			"pwd":123456
		},
		success: function(msg) {
			console.log(msg);
		}
	})

前端响应

2.4 get 请求返回 json 数据

后端接口编写

代码语言:javascript
复制
@app.route("/ajax/js")
def ajax_json():
    person = {"id":3324,"username":"coco","password":'3329wdadwda',"hobbies":["篮球","唱歌","跳舞"]}
    return jsonify(person)

可以看到也面返回了 JSON 格式的数据

前端 js

代码语言:javascript
复制
	// 获取 json 数据
	$.ajax({
		url: "http://127.0.0.1:3000/ajax/js",
		type: "get",
		dataType:"json",
		success: function(msg) {
			console.log(msg);
		}
	})

数据正常响应了

三、原生 Promise

3.1 什么是 Promise?

Promise 是异步编程的解决方案,是一个对象,可以获取异步操作的信息,可以看做是 ajax 的升级版,这个可以直接使用,不需要引入 第三方包

3.2 Promise 的基本使用

  1. 实例化 Promise 对象。构造函数中传递函数,该函数用于处理异步任务
  2. resolve 和 reject 两个参数用于处理成功和失败的两种情况,并通过 p.then 获取处理结果
代码语言:javascript
复制
		<script>
			console.log(typeof Promise);
			let p = new Promise(function(resolve,reject){
				// 成功调用 resolve
				// 失败调用 reject
				setTimeout(function(){
					let flag = true;
					if (flag) {
						// 正常情况
						resolve('hello');
					} else {
						reject('出错了');
					}
				},100);
			});
			
			p.then(function(data){
				// 从 resolve 得到正常结果
				console.log(data);
			},function(info) {
				// 从 reject 得到结果
				console.log(info);
			});
		</script>

3.3 使用 Promise 发起 ajax 请求

编写 Promise 的测试案例的后台接口

代码语言:javascript
复制
@app.route("/data")
def data():
    return "Hello World"

@app.route("/data1")
def data1():
    return "Hello Tom"

@app.route("/data2")
def data2():
    return "Hello Jerry"

js 处理

代码语言:javascript
复制
		<script>
			// 基于 Promise 发起 Ajax 请求,这里我们使用 Promise 封装了 ajax
			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);
				});
				// then 的返回值情况
				// 1. then 返回 Promise 实例对象,调用下一个 then,
				// 2. 第二种,直接在 then 返回 具体值,下一个 then 皆可以得到具体的值
				return p;
			}
			
			queryData('http://127.0.0.1:3000/data')
			.then(function(data) {
				// 执行成功
				console.log(data);
			},function(info) {
				// 执行失败
				console.log(info);
			});
			
			// 发送多个 ajax 请求,并且保证顺序, 解决回调地狱问题,then 就很好的解决了
			queryData('http://127.0.0.1:3000/data')
			.then(function(data) {
				// 执行成功
				console.log(data);
				return queryData("http://127.0.0.1:3000/data1");
			})
			.then(function(data) {
				// 执行成功
				console.log(data);
				return queryData("http://127.0.0.1:3000/data2");
				// return hello
			})
			.then(function(data) {
				// 执行成功
				console.log(data);
			});
		</script>

结果:

3.4 Promise API

  1. p.then() 得到异步正常结果
  2. p.catch() 捕获异常(等价于得到 reject 的返回值)
  3. p.finally() 不管成功,失败都会执行

js 处理

代码语言:javascript
复制
		<script>
			// p.then() 得到异步正常结果
			// p.catch() 捕获异常
			// p.finally() 不管成功,失败都会执行
			
			function foo() {
				return new Promise(function(resolve, reject) {
					setTimeout(function() {
						// resolve('123'); // then 接收
						reject('error'); //catch 接收
					},100);
				})
			}
			// foo()
			// .then(function(data) {
			// 	console.log(data); // 打印 123
			// })
			// .catch(function(data) {
			// 	console.log(data); 
			//  })
			//  .finally(function() {
			// 	 console.log('finished')
			//  })
			
			// 两种编写方式等价
			foo()
			.then(function(data) {
				console.log(data); // 打印 123
			}, function(data) {
				console.log(data); 
			})
			 .finally(function() {
				 console.log('finished')
			 })
		</script>

四、fetch api

fetch 是 Promise 和 xmlHttpRequest 的升级版,使用起来会更加的便捷

4.1 fetch 基本使用

后端 api 搭建

代码语言:javascript
复制
@app.route('/fdata')
def fdata():
    return 'Hello Fetch'

前端 js

代码语言:javascript
复制
		<!-- 基于 Promise, xhr 升级版本 -->
		<script type="text/javascript">
			fetch('http://127.0.0.1:3000/fdata').then(function(data) {
				// text() 方法属于 fetchAPI 的一部分  它返回 promise 实例对象, 所以要通过返回 data.text() 得到服务器的返回数据,data.json() 则返回json 数据
				console.log(data);
				return data.text(); 
			}).then(function(data) {
				console.log(data);
			});
			
			// 返回 JSON,这里用到了前面编写的 JSON API
			fetch('http://127.0.0.1:3000/ajax/js').then(function(data) {
				return data.json(); 
			}).then(function(data) {
				console.log(data);
			});
			
		</script>

前端响应结果

4.2 fetch 发起带参数的 get 请求

接口前面有写过,这里只写前端

代码语言:javascript
复制
		<script>
			// 指定返回类型
			//  1. data.text() 字符串
			// 2. data.json() 返回JSON ,同 JSON.parse(responseText)

			fetch('http://127.0.0.1:3000/ajax/data1?uname=123&pwd=223')
				.then(function(data) {
					return data.text();
				}).then(function(res) {
					console.log(res);
				});
		</script>

4.3 fetch 发起post 请求,并带参数

代码语言:javascript
复制
	fetch('http://127.0.0.1:3000/ajax/post', {
			method: 'POST',
			body: {
				"uname":123,
				"pwd":223
			}
		})
		.then(function(data) {
			return data.text();
		}).then(function(res) {
			console.log(res);
		});

但是遇到 小 BUG了

4.4 fetch 发送 get 请求, 返回 JSON 数据

代码语言:javascript
复制
	// 返回 JSON,这里用到了前面编写的 JSON API
	fetch('http://127.0.0.1:3000/ajax/js').then(function(data) {
		return data.json(); 
	}).then(function(data) {
		console.log(data);
	});

四、更好的封装 axios?

axios 在 vue 中使用的会比较多,也是一个 第三方的 http 请求库,可以在 Github 中找得到。

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

它具有以下特征

  1. 支持游览器和 node.js
  2. 支持 promise
  3. 能拦截请求和相应
  4. 自动转换 JSON 语句

4.1 axios 的基本使用

我们需要在使用之前引入 axios 库

后端 api 的编写

代码语言:javascript
复制
@app.route('/adata')
def adata():
    return 'Hello axios'
代码语言:javascript
复制
	// 语法使用
	axios.get('/data')
		.then(function(res) {
			// data 属性名是固定的,用于相应后台数据
			console.log(res.data);
		})
		
	// 最简单的 axios 使用,通过 .data 获取数据,固定用法
	axios.get('http://localhost:3000/adata').then(function(res) {
		console.log(res.data);
	})

4.2 axios 常用 API

4.2.1 get 请求

后端 API 编写

代码语言:javascript
复制
@app.route('/axios')
def axiod():
    id = request.args.get("id")
    return f'axios 传递参数 {id}'

# 获取 restfull 参数
@app.route("/axios1/")
def axios(id):
    return f'axios1 restfull 传递参数 {id}'


@app.route('/axios2')
def axios2():
    id = request.args.get("id")
    name = request.args.get("name")
    return f"axios2 传递的名称:{name}, id 为:{id}"

js 编写

代码语言:javascript
复制
	axios.get('http://localhost:3000/axios?id=132').then(function(res) {
		console.log(res.data);
	})

	// restfull 
	axios.get('http://localhost:3000/axios1/223').then(function(res) {
		console.log(res.data);
	})

	axios.get('http://localhost:3000/axios2', {
		params: {
			"id": 123,
			"name": "coco"
		}
	}).then(function(res) {
		console.log(res.data);
	})

前端响应结果

4.2.2 post 请求

还找找 bug

本文参与?腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-05-10 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客?前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
  • 一、后端 API 服务搭建
  • 二、原生 ajax
    • 2.1 不带参数的 get 请求
      • 2.2 带参数的 get 请求
        • 2.3 带参数的 post 请求
          • 2.4 get 请求返回 json 数据
          • 三、原生 Promise
            • 3.1 什么是 Promise?
              • 3.2 Promise 的基本使用
                • 3.3 使用 Promise 发起 ajax 请求
                  • 3.4 Promise API
                  • 四、fetch api
                    • 4.1 fetch 基本使用
                      • 4.2 fetch 发起带参数的 get 请求
                        • 4.3 fetch 发起post 请求,并带参数
                          • 4.4 fetch 发送 get 请求, 返回 JSON 数据
                          • 四、更好的封装 axios?
                            • 4.1 axios 的基本使用
                              • 4.2 axios 常用 API
                              相关产品与服务
                              API 网关
                              腾讯云 API 网关(API Gateway)是腾讯云推出的一种 API 托管服务,能提供 API 的完整生命周期管理,包括创建、维护、发布、运行、下线等。
                              领券
                              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
                              http://www.vxiaotou.com