赞
踩
python flask?
着摸不透的js?
丑到爆的网页?
不,这才是你需要的:
这是一个博客网站,用户可以登录 注册 写博客 发评论
实现大吞吐量,高并发!
安装python虚拟环境及支持库
pip install venv::安装venv支持库,python3.3后自带
python -m venv [虚拟环境名称]
venv/bin/scripts/active.bat::激活环境,可以看到命令行左侧出现 (venv) 字样
pip install [第三方支持库名称]
我们需要的第三方支持库有flask pymysql
内置库有hashlib uuid
安装mysql及navicat15
登录注册:/login?goto=[重定向]
看文章:/article/< int:id >
编辑文章:/editor?id=[文章id]
start.py最初版本
from flask import Flask,route,render_template def runcom(form): '''解析post请求''' return " " #不能返回空值,否则flask会报错 app=Flask(__name__) @app.route("/",methods=["GET"]) def index(): return render_template("index.html") @app.route("/login") def login(): return render_template("login.html") @app.route("/editor") def editor(): return render_template("login html") @app.route("/article/<int:id>") def read(id): return render_template("article.html",id=id) @app.route("/post",methods=["POST"]) def postHandler(): data=request.form#获取post报文 return runcom(data) if __name__="__main__": app.run(host="0.0.0.0")
runcom这个函数会解析网站post请求,目前什么也没写,到下一节就会写功能
验证模块,即登录注册功能,是一个网站必不可少的功能
登录注册需要 (前端 服务器 数据库) 三者交互
userinfo
使用form表单发送POST请求
<form action="/post" type="post" target="/">
<input type="hidden" name="command" value="login">
<input type="text" name="username" id="id">
<input type="password" name="password" id="pw">
<input type="submit">
</form>
或者使用jQ中的ajax
id=document.getElementById("id")
pw=document.getElementById("pw")
$.ajax({"type":"POST",
data:{"command":"login","id":id,"password":pw}
})
同时,我们在start.py中的runcom函数中加几行代码。
import uuid cursor=pymysql.connect(host="127.0.0.1",database="web",user="root",password="root") def runcom(form): command=form.get("command") if command==None: return{"success":"false","content":"请指定command项"} if command=="login": id=from.get("id") pw=from.get("password") if un==None or pw==None: return{"success":"false","content":"请指定id项或password项"} cursor.execute("SELECT pw FROM userinfo WHERE id="+id) passwd=cursor.fetchone() if passwd==None: return{"success":"false","content":"用户不存在"} if passwd[0]!=pw: return{"success":"false","content":"密码错误"} #以上为验证登录 #成功后的操作--分配uuid uid=uuid.uuid4().replace("-","")#不要与uuid重名 cursor.execute("UPDATE userinfo uuid VALUES("{}") WHERE id={}".format(uid,id)) return{"success":"false","uuid":uid}
为什么要用uuid?
UUID 是 通用唯一识别码(Universally Unique Identifier)的缩写,是一种软件建构的标准,亦为开放软件基金会组织在分布式计算环境领域的一部分。其目的是,让分布式系统中的所有元素,都能有唯一的辨识信息,而不需要通过中央控制端来做辨识信息的指定。如此一来,每个人都可以创建不与其它人冲突的UUID。 一一 百度百科
每一个用户有自己唯一的uuid,服务器只需在用户每次操作时判断 用户和uuid
是否匹配就行了,而不是每次都要用户输密码。
但是,uuid要不断更新(一般是在用户登录的时候),这样可以防止uuid滥用,否则,一但别人拿到了你的uuid,就可以用你账号为所欲为[手动滑稽]
顺便一提,前端接受uuid后会放在cookie,所以破解 某某云限速 的方法就是让用户先登录,取cookie中的uuid,然后为所欲为……
使用form表单发送POST请求
<form action="/post" type="post" target="/">
<input type="hidden" name="command" value="register">
<input type="text" name="username" id="username">
<input type="submit">
</form>
或者使用jQ中的ajax
name=document.getElementById("username")
$.ajax({"type":"POST",
data:{"command":"register","username":name}
})
同样,我们在start.py中的runcom函数中加几行代码。
def runcom(form):
#--(前略)--
if command=="register":
un=form.get("username")
pw=form.get("password")
if un==None or pw==None:
return{"success":"false","content":"请指定username项或password项"}
cursor.execute("SELECT pw FROM userinfo WHERE username="+str(un))
passwd=cursor.fetchone()
if passwd!=None:
return{"success":"false","content":"用户已存在"}
cursor.execute("INSERT INTO userinfo(username,password) VALUES("{}","{}")".format(un,pw))
id=cursor.lastrowid#分配id
return{"success":"true","id":id,"username":username}
补充下uuid的优点:
#判断id,uuid是否匹配 def isNum(string): for s in string: if s<"0" or s>"9": return False return True def isMatch(id,uuid): if isNum(id)==False: return{"success":"false","content":"id不是纯数字"} cursor.execute("SELECT uuid FROM userinfo WHERE id="+id) uid=cursor.fetchone() if None==uid: return{"success":"false","content":"用户不存在"} if uuid!=uid[0]: return{"success":"false","content":"id和uuid不匹配(登录失效)"} return True
以后用户操作,比如发动态
post请求就可以这么写:
{"commamd":"bling","id":用户id,"uuid":"uuid","say":"评论内容"}
这样服务器就可以识别用户了
文章模块才是重头戏。
文章模块分 读文章,写文章和展示文章列表,以及点赞、评论、收藏 等功能
读文章很容易,我们在[网站根目录]/static下创建一个文件夹,就叫articles好了,它用于存放写好的文章,每篇文章存放在 [对应的id].html里
网站取的时候,直接GET请求拿到文章就ok了
用iframe嵌入文章
<iframe src="/static/articles/{{id}}.html">
<!文章内容-->
</iframe>
注意! articles文件夹不要放在除static及其子目录的其它地方,否则GET请求时就算给出文章路径,flask也会识别为路由请求,而不是static(静态文件)
什么是路由请求?什么是路由请求?
如果你想知道答案,且看:
from flask import Flask,route
app=Flask(__name__)
@app.route("/hello")
def func1():
'''当访问/hello时,会返回Hello World!'''
return "Hello World!"
flask用Flask对象(app是一个Flask对象)的route装饰器设定访问路径
route装饰器还可以传参
@app.route("/hello/<str:name>")
def func2(name):#住意参数
'''当访问/hello/<name>时,会返回"Hello "+name '''
return "Hello "+name
根据这个设定,我们可以设定读文章的路径:/article/< int:id >
@app.route("/article/<int:id>")
def readArticle():
return render_template("article.html",id=id)
#flask模板函数,"id=id"会把网页里{{id}}渲染成变量id
<iframe src="/static/articles/{{id}}.html"></iframe>
就ok了
需求分析:
路由为/editor?id=[文章id]
文章id不为空,则判断用户是否为文章作者,否则无权编辑
文章id为空,新建一篇文章
POST请求是
{"command":"publish","id":[用户id],"uuid":[uuid],"article":[文章内容],"artID":[文章id,可空]}
我们可以这么写路由
@app.route("/editor")
def editor():
return render_template("editor.html")
/editor?id=[用户id]中的 id参数 可以用getParameters([arg])获取,这个函数网上一搜一大堆
function getParameter(name) { var reg = new RegExp((^&) + name + =([^&])(&$), i); var r = window.location.search.substr(1).match(reg); if (r != null) return unescape(r[2]); return null; } //然后就是判断是否为文章作者 function checkAuthor(){ userID=getCookie("id") if(userID==""){windows.location.herf="/login?goto="+windows.location.herf} artID=getParameter("id") if(artID==null) return; $.ajax({data:{"command":"article","id":id} success: function(res){ if(res["author"]!=userID){ alret("您无权编辑这篇文章") windows.location.href="/" } } }) } function publish(){ id=getCookie("id") uuid=getCookie("uuid") content=document.getElementById("content").innerHTML $.ajax({url:"/post", data:{"command":"publish","id":id,"uuid":uuid,"content":content}}) }
html方面,就放一个textarea和一个用于发布的Button
<textarea id="content"></textarea>
<button action="publish()"></button>
在mysql建一张relations的表,用于保存用户关系
relations{
userA int(32) ;用户A < 用户B
userB int(32)
isFriend tinyint
isFollow tinyint ;关注
isFollowing tinyint ;粉丝
}
SELECT 属性 FROM relations WHERE userA=用户A and userB=用户B
UPDATE 属性 VALUES(值) FROM relations WHERE userA=用户A and userB=用户B
登录注册:/login?goto=[重定向]
看文章:/article/< int:id >
编辑文章:/editor?id=[文章id]
开始我们主要讲了后端代码,而前端基本都是“三行论”
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。