实现一个微博功能:
- 前端用 ajax 发送 HTTP 请求到后端
- 后端 API操作元素
- ajax 跨域
在当前,js文件只能向当前界面发送数据,通过相关设置后,本地js文件能向不同端口、不同域名发送数据; - ajax weibo 和动态评论
self.parentElement.remove()
前端是JSON.stringify 和 JSON.parse()
后端是json.dumps 和 json.loads
序列化(在进行序列化前一定要是 数组/列表 格式):
json.dumps()是将python格式的数组/列表,转换为json格式的字符串
反序列化:
json.loads()是将json格式的字符串,还原成python格式的数组/列表
一、加载index,通过js文件展现所有weibo
后端的路由函数:
在文章结尾有all的数据
def all(request):
weibo_list = Weibo.all()
# json()是将数据转换为字典,因为在dumps(序列化)前,数据必须是字典数组
# 再通过encode编码,进行传输,无论什么格式,在传输(utf-8)前(unicode)都需要encode,拿出来需要decode;
weibos = [w.json() for w in weibo_list]
return json_response(weibos)
def json(self):
#返回当前 model 的字典表示
# copy 会复制一份新数据并返回
d = self.__dict__.copy()
return d
@classmethod
def all(cls):
# all 方法(类里面的函数叫方法)使用 load 函数得到所有的 models
path = cls.db_path()
models = load(path)
# 这里用了列表推导生成一个包含所有 实例 的 list
# m 是 dict, 用 cls._new_from_dict(m) 可以初始化一个 cls 的实例
# 不明白就 log 大法看看这些都是啥
ms = [cls._new_from_dict(m) for m in models]
return ms
def json_response(data):
#本函数返回 json 格式的 body 数据,前端的 ajax 函数就可以用JSON.parse 解析出格式化的数据
# 注意, content-type 现在是 application/json 而不是 text/html
# 这个不是很要紧, 因为客户端可以忽略这个
header = 'HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n'
# json.dumps 用于把 list 或者 dict 转化为 json 格式的字符串
# ensure_ascii=False 可以正确处理中文,indent=2 表示格式化缩进, 方便好看用的
body = json.dumps(data, ensure_ascii=False, indent=2)
r = header + '\r\n' + body
return r.encode(encoding='utf-8')
前端的元素操作:
(1)首先执行这个函数,apiWeiboall()里面包裹的function(r){...}是回调函数,最后执行,先当做是apiWeiboall()函数里面的一个参数。那么开始执行apiWeiboall()函数;
var loadsWeibos = function(){
apiWeiboall(function(r){
var weibos = JSON.parse(r)
for (var i = 0; i < weibos.length; i++){
var weibo = weibos[i]
insertWeibo(weibo)
}
})
}
回调函数拿到参数后,首先需要利用JSON.parse()进行解码,因为收到的是JSON格式的字符串,解码后是python类型的数组/字典
// 功能函数
(2)根据定义的path,执行ajax函数
var apiWeiboall = function(callback){
var path = '/api/weibo/all'
ajax('GET', path, '', callback)
}
var weiboTemplate = function(weibo){
// 以id 来定位微博,方便所属的评论查找。id不能是纯数字,注意格式
var w = `
<div class='weibocell'>
<button class = 'weibo-delete' data-id = ${weibo.id}>删除</button>
<button class = 'weibo-edit' data-id = ${weibo.id}>编辑</button>
<span id=weibo${weibo.id} class='weibo_content'>${weibo.content}</span>
</div>
`
return w
}
JS参数的传递:${weibo.content}
id的值不能为纯数字,所以可以这样:weibo${weibo.id}
var insertWeibo = function(weibo){
var weiboCell = weiboTemplate(weibo)
var weiboList = e('.weibo-list')
weiboList.insertAdjacentHTML('beforeEnd', weiboCell)
}
// 函数执行入口
下划线__去掉也可以,知识为了显得特别;
通过函数入口,执行里面包裹的函数;
var __main = function(){
loadsWeibos()
}
__main()
脚本函数
var log = function() {
console.log.apply(console, arguments)
}
var e = function(sel) {
return document.querySelector(sel)
}
XMLHttpRequest 对象
XMLHttpRequest 对象用于在后台与服务器交换数据,能够:
- 在不重新加载页面的情况下更新网页
- 在页面已加载后从服务器请求数据
- 在页面已加载后从服务器接收数据
- 在后台向服务器发送数据
// ajax 函数
步骤:
- 创建实例
new
- 设置请求方法和地址,true是异步
open()
方法打开连接 - 设置发送数据的格式
- 将数据转换为JSON格式地字符串格式
JSON.stringify()
函数 - 发送
var ajax = function(method, path, data, responseCallback) {
var r = new XMLHttpRequest()
r.open(method, path, true)
r.setRequestHeader('Content-Type', 'application/json')
// 注册响应函数 ‘===’为绝对等于
r.onreadystatechange = function() {
if(r.readyState === 4) {
// r.response 存的就是服务器发过来的放在 HTTP BODY 中的数据
responseCallback(r.response)
}
}
// 把数据转换为 json 格式字符串
data = JSON.stringify(data)
// 发送请求
r.send(data)
}
里面的 r.onreadystatechange()函数是个回调函数。当请求被发送到服务器时,我们需要执行一些基于响应的任务。每当 readyState 改变时,就会触发 onreadystatechange 事件。readyState 属性存有 XMLHttpRequest 的状态信息:
0: 请求未初始化
1: 服务器连接已建立
2: 请求已接收
3: 请求处理中
4: 请求已完成,且响应已就绪
也就是,当XMLHttpRequest发送完数据后,这个函数就一直等着,当状态码为4时,将调用这个回调函数,参数r.response
为服务器发送过来的数据。然后再慢慢往回执行这个回调函数。
ajax() -- apiWeiboall() -- loadsWeibos()
抓包:
浏览器按F12,在网络-所有,里面有浏览器的所有请求以及服务器发送的数据
网友评论