前言:本文是学习网易微专业的《python全栈工程师 - Flask高级建站》课程的笔记,欢迎学习交流。同时感谢老师们的精彩传授!
一、课程目标
- json数据格式
- ajax提交
- jQuery的ajax实现
二、详情解读
2.1.json数据格式
json
格式是一种字符串格式,比如:
'[{"upload": 1, "fileName": "foo.jpg", "url": "/files/foo.jpg"}]'
他是一个字符串,但是看上去就好像是列表与字典组成的结构。
为什么使用json
格式:
在网页访问期间,前端只能向后端发送字符串,不能发送其他任何类型的数据,比如数组,对象。通过把json
对象转换为字符串格式,就可以通过互联网传输,而且无论js,python,java,php
都支持json
的编码与解码。
2.1.1.python对json的支持
json
模块:
1.导入模块:import json
2.将对象转换为json
字符串 - json.dumps()
3.将json
字符串转换为python
列表与数组 - json.loads()
2.1.2.js对json的支持
js
提供了一个JSON
对象
1.将对象转换为json
字符串 - JSON.stringify()
2.将json
字符串转换为js
的数组与对象 - JSON.parse()
2.2.ajax数据提交
2.2.1.ajax技术
ajax
技术称为无刷新数据提交,表单提交过程会带来整个页面的刷新,如果发生错误,卡顿,对用户的体验很不好。现代浏览器都支持一种称不xhr
的对象向后台提交数据。
实操:(这部分是测试用的)
Step1
:新建文件夹templates/ajax
,并在ajax
目录下创建文件form.html
,写入以下代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{% if message %}
{{ message }}
{% endif %}
<form action="" method="post">
<input type="text" name="name">
<input type="password" name="password" id="password">
<input type="submit" name="submit" value="提交">
</form>
</body>
</html>
Step2
:在app.py
中添加test_form()
视图函数:
# 测试ajax的异步提交
@app.route('/form', methods=['GET', 'POST'])
def test_form():
from time import sleep
message = None
if request.method == 'POST':
pass
sleep(3)
message = '提交数据有问题,失败'
return render_template('ajax/form.html', message=message)
xhr异步提交
xhr = new XMLHttpRequest()
xhr.open("get", "url", async) // async默认为true,异步提交,否则为同步
xhr.send()
xhr
对象拥有readyState
属性,该属性值为请求状态:
0(UNSET)
:未初始化。尚未调用open()
方法
1(OPENED)
:启动。已经调用open()
方法,但尚未调用send()
方法
2(HEADERS_RECEIVED)
:发送。已经调用send()
方法,且接收到头信息
3(LOADING)
:接收。已经接收到部分响应主体信息
4(DONE)
:完成。已经接收到全部內数据,而且已经可以在客户端使用了。
可以在xhr
对象的readystatechange
事件绑定一个处理方法:
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status == 200) {
alert(xhr.responseText);
}
}
实操:(这部分也是测试用)
Step1
:将app.py
中的test_form()
视图函数修改为以下内容:
@app.route('/form', methods=['GET', 'POST'])
def test_form():
from time import sleep
message = None
if request.method == 'POST':
pass
message = '数据处理success'
return message
return render_template('ajax/xhr.html', message=message)
step2
:新建文件templates/ajax/xhr.html
,写入以下内容:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="message"></div>
<ul id="news"></ul>
<input type="text" name="name" value="">
<select name="newstype" id="newstype">
<option value="1">新闻</option>
<option value="2">专题</option>
</select>
<input type="button" name="btn" id="btn" value="提交">
<script>
btn = document.getElementById('btn')
message = document.getElementById('message')
ul = document.getElementById('news')
// xhr是XMLHttpRequest对象的简称
// 可以直接在页面内发起请求
// 从而可以在不刷新页面的情况加载数据
// 经常加载json格式数据
// 在js中,json格式数据使用JSON对象进行编解码
// JSON.parse('["网易", "微专业", "助你成才"]') - 解码
// JSON.stringify(["网易", "微专业", "助你成才"]) - 编码
// readyState === 4 请求结束
// status == 200 请求状态码。 200为正常响应
// responseText 服务器返回的数据,如果是json字符串格式,可以JSON对象解析
xhr = new XMLHttpRequest()
xhr.onreadystatechange = function(ev) {
console.log(this.readyState)
console.log(this.status)
if (this.readyState == 4 && this.status == 200) {
console.log('服务器返回:', this.responseText)
message.innerHTML = this.responseText
}
}
btn.onclick = function() {
// 为xhr创建数据
message.innerHTML = "请等待..."
data = new FormData()
data.append('newstype', document.getElementById('newstype').value)
// 第一个参数请求方法:get、post
// get方法,send不用传递数据,通过get的url传送数据
// post方法,send传递FormData对象数据
// 第二个参数是请求地址
// 第三个参数是同步还是异步,默认异步,同步状态下,必须等待响应结果
// 才能执行下一步js
xhr.open("post", '{{ url_for("test_form") }}', true)
xhr.send(data)
}
</script>
</body>
</html>
页面显示及点击提交的运行结果:
实操2: 测试从服务器端返回列表或字典数据
Step1
:修改app.py
的test_form()
视图函数,以下内容:
@app.route('/form', methods=['GET', 'POST'])
def test_form():
import json
if request.method == 'POST':
newstype = request.form['newstype']
lists = {
"1": ["新闻1","新闻2","新闻3"],
"2": ["头条1","头条2","头条3"]
}
return json.dumps(lists[newstype])
return render_template("ajax/xhr.html")
Step2
:修改templates/ajax/xhr.html
为以下代码:
.
.
.
xhr.onreadystatechange = function(ev) {
console.log(this.readyState)
console.log(this.status)
if (this.readyState == 4 && this.status == 200) {
// 修改这里的代码
data = JSON.parse(this.responseText)
for(i in data) {
ul.innerHTML += "<li>" + data[i] + "</li>"
}
}
}
.
.
.
分别提交”新闻“和”专题“的运行结果:
2.3.jQuery的ajax封装
上面用的xhr
对象,在IE
浏览器中并不能运行。而jQuery
的ajax
封装兼容性更好,用起来更方便。
jQuery
提供了ajax
封装对象。
1.标准的使用方式:
$.ajax({
type: "POST", // 必写
url: "http://127.0.0.1/register/", // 必写
data: data,// 必写
contentType: ,
processData: false,
beforeSend: function() {},
compplete: function(){},
success: function(result){},// 必写
error: function(e){}
});
2.快速使用方式:
dom
加载url
$(dom).load(url) // 加载的url内容填充dom节点
get
请求
$.get(url, data, callback)
post
请求
$.post(url, data, callback)
实操:(这部分也是测试用)
Step1
:新建文件templates/ajax/jquery.html
,写入以下代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="/static/js/query-3.4.1.min.js"></script>
</head>
<body>
<div id="message"></div>
<ul id="news"></ul>
<input type="text" name="name" value="">
<select name="newstype" id="newstype">
<option value="1">新闻</option>
<option value="2">专题</option>
</select>
<input type="button" name="btn" id="btn1" value="ajax提交">
<input type="button" name="btn" id="btn2" value="get提交">
<input type="button" name="btn" id="btn3" value="post提交">
<script>
btn1 = document.getElementById('btn1')
btn2 = document.getElementById('btn2')
btn3 = document.getElementById('btn3')
message = document.getElementById('message')
ul = document.getElementById('news')
// $.ajax参数对象
// type:请求方式 get、post
// data:提交数据
// dataType:返回数据类型 text - 普通文本 json - json格式
btn1.onclick = function(){
$.ajax({
type: 'POST',
data: {"newstype": "1"}
dataType: "json",
success: function(data) {
for ( i in data) {
ul.inneHTML += "<li>" + data[i] + "</li>"
}
}
})
}
// 加载一个页面到元素
{# $('.message').load("/form") #}
// get方式简写
btn2.onclick = function(){
$.get('/form', function(data) {
$('#message').html(data)
})
}
// post方式简写
btn3.onclick = function() {
$.post('/form', {'newstype': '2'}, function(data) {
for (i in data) {
ul.innerHTML += "<li>" + data[i] + "</li>"
}
}, dataType="json")
}
</script>
</body>
</html>
实操2: 将发布文章改为ajax
异步提交
Step1
:修改templates/artilce/post.html
中发布文章的的type="button"
:
.
.
.
<div class="form-group">
<!-- 这里将原来的submit改为button-->
<input class="btn" type="button" name="submit" id="btn1" value="发表文章" />
<input class="btn" type="reset" name="btn2" id="btn2" value="重设" />
</div>
.
.
.
Step2
:继续在post.html
中添加以下js
代码:
<script>
btn = document.getElementById('btn1')
btn.onclick = function(ev){
cate_id = $('#cate').val()
title = $('#title').val()
intro = $('#intro').val()
content = CKEDITOR.instances['content'].getData()
if (title == '') {
$('#title').focus()
return false
}
if (intro == '') {
$('#intro').focus()
return false
}
$.ajax({
type: 'POST',
data: {
'cate': cate_id,
'title': title,
'intro': intro,
'content': content
},
dataType: 'json',
success: function(data) {
$('#message').html(data.message)
// 表单重置,相当于点击重设按钮
// 这里有个坑,下面这一行代码要想生效,上面html代码里的reset按钮中的name和id都不可以等于“reset"
// 否则会报错$(...)[0].reset() is not a function
$("form")[0].reset()
CKEDITOR.instances['content'].setData()
}
})
}
</script>
Step2
:替换views/articles.py
中的post()
视图函数为以下代码:
@article_app.route("/post", methods=['get','post'])
@login_required
def post():
if request.method == "POST":
cate_id = request.form['cate']
title = request.form['title']
intro = request.form['intro']
content = request.form['content']
article = Article(
cate_id = cate_id,
title=title,
intro=intro,
content=content,
author="luxp"
)
db.session.add(article)
db.session.commit()
# 由于我们是在article_app模块下
# 因此url_for中的视图函数名可以省略article_app
import json
message = {'message': '发布成功'}
# 因为是异步提交,这里返回的是json数据
return json.dumps(message)
# return redirect(url_for(".list"))
return render_template("article/post.html")
三、课程小结
- json数据格式
json
串是一种字符串,而不是一种传输方式,传输的方式我们采用的是ajax
方式。 ajax
技术jQuery
的ajax
封装
第1章~第6章代码地址: https://pan.baidu.com/s/1FfgbrIw0VwtUDJ-ZVUiAL
,提取码:d7ke