准备工作

   在学习Django之前,先动手撸一个简单的WEB框架来熟悉一下前后端交互的整体流程

   本次用到的模块:

   1.wsgiref,这是一个Python自带的模块,用于构建路由与视图

   2.pymysql,第三方模块,用于数据库与视图层进行数据交互

   3.jinja2,第三方模块,用于对前端页面进行模板渲染

   请使用pip install modulename进行安装

   如果安装jinja2失败,请使用easy_install Jinja2命令进行安装

数据交互

   其实前面已经有大量的地方讨论浏览器与后端服务器如何进行交互,也用socket进行实现过简单的交互,但是我们需要在前者基础上做一个优化,即用户在地址栏输入什么路径,就返回请求的路径名字。

   当这个需求完成后,我们就可以根据不同的请求路径,返回出不同的HTML文档信息,但是使用原生的socket这个过程会十分的繁琐,所以用一次就放弃吧。

from socket import *

def run():
server = socket(AF_INET, SOCK_STREAM) # 传输层基于TCP协议
server.bind(("127.0.0.1", 8080))
server.listen(5) while 1: conn, addr = server.accept()
try: # 防止Windows平台下Client端异常关闭导致双向链接崩塌Server端异常的情况发生
data = conn.recv(1024)
if not data: # bug修复:针对类UNIX环境
continue request_path = data.decode("utf-8").split(" ")[1] # 拿到请求的路径
conn.sendall(bytes("HTTP/1.1 201 OK \r\n\r\n", "utf8")) # 返回响应头
conn.sendall(bytes("<h1>{0}</h1>".format(request_path), "utf8")) # 返回响应体 except Exception:
continue conn.close() if __name__ == '__main__':
run()

  

wsgiref

   以下是利用wsgiref实现上面的功能,简单了许多,并且代码变得更加明了。

   此外新增加了访问路径不存在时给出404错误提示。

from wsgiref.simple_server import make_server

def index(request):
return "You visited index" def login(request):
return "You visited login" def error(request):
return "404 Resource request error" urls = [
("/index", index),
("/login", login),
] def run(request, response): """
request:① 请求相关的所有数据
response:② 响应相关的数据
return:③ 返回给浏览器的数据
""" response("200 OK",[]) # 响应首行,响应头
func = None
request_path = request.get("PATH_INFO") # 拿到路径 for url in urls:
if request_path == url[0]:
func = url[1]
break # 匹配到后结束for循环 if func:
res = func(request)
else:
res = error(request) return [res.encode("utf-8")] if __name__ == '__main__':
server = make_server("localhost", 8080, run)
# ③ 实时监听127.0.0.1:8080地址,只要有链接请求,都交给run函数处理
server.serve_forever() # ④ 开启服务

  

代码解耦

   我们对上述代码进行解耦,将不同功能的代码放在不同的文件夹下。

  

-- webproject
-- view # 视图相关代码
-- view.py
-- urls # 路由相关代码
-- urls.py
-- run.py # 启动相关代码
# view.py

def index(request):
return "You visited index" def login(request):
return "You visited login" def error(request):
return "404 Resource request error"
# urls.py

from view.view import *

urls = [
("/index", index),
("/login", login),
]
# run.py

from wsgiref.simple_server import make_server
from urls.urls import * def run(request, response): """
request:① 请求相关的所有数据
response:② 响应相关的数据
return:③ 返回给浏览器的数据
""" response("200 OK",[]) # 响应首行,响应头
func = None
request_path = request.get("PATH_INFO") # 拿到路径 for url in urls:
if request_path == url[0]:
func = url[1]
break # 匹配到后结束for循环 if func:
res = func(request)
else:
res = error(request) return [res.encode("utf-8")] if __name__ == '__main__':
server = make_server("localhost", 8080, run)
# ③ 实时监听127.0.0.1:8080地址,只要有链接请求,都交给run函数处理
server.serve_forever() # ④ 开启服务

返回页面

   继续上面的流程,已经将代码进行解耦了,此时我们新建一个template文件夹用于专门存放返回的网页。

   并在该文件夹下新建index.html以及login.html

-- webproject
-- view # 视图相关代码
-- view.py
-- urls # 路由相关代码
-- urls.py
-- template # 前端页面
-- index.html
-- login.html
-- run.py # 启动相关代码

<!DOCTYPE html>
<html lang="en"> <head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src='https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js'></script>
<link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css'
integrity='sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u' crossorigin='anonymous'>
<script src='https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js'
integrity='sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa'
crossorigin='anonymous'></script>
<title>Document</title>
<style> .carousel .item {
height: 400px;
background-color: #777;
} .carousel-inner>.item>img {
position: absolute;
top: 0;
left: 0;
min-width: 100%;
height: 100%;
}
</style>
</head> <body> <nav class="navbar navbar-inverse">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">INDEX</a>
</div> <!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<form class="navbar-form navbar-left">
<div class="form-group">
<input type="text" class="form-control" placeholder="Search">
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
<ul class="nav navbar-nav navbar-right">
<li><a href="HTTP://127.0.0.1:8080/login">LOGIN</a></li>
<li><a href="#">REGISTER</a></li>
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav> <div class="container-fluid"> <div class="row">
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12 input-lg-5g bg-primar ">
<div class="page-header">
<h1>Example page header <small>Subtext for header</small></h1>
</div>
</div> <div class="col-xs-3 col-sm-3 col-md-3 col-lg-3">
<div class="list-group">
<a href="#" class="list-group-item active">
Cras justo odio
</a>
<a href="#" class="list-group-item">Dapibus ac facilisis in</a>
<a href="#" class="list-group-item">Morbi leo risus</a>
<a href="#" class="list-group-item">Porta ac consectetur ac</a>
<a href="#" class="list-group-item">Vestibulum at eros</a>
</div>
</div> <div class="col-xs-9 col-sm-9 col-md-9 col-lg-9">
<div id="carousel-example-generic" class="carousel slide" data-ride="carousel">
<!-- Indicators -->
<ol class="carousel-indicators">
<li data-target="#carousel-example-generic" data-slide-to="0" class="active"></li>
<li data-target="#carousel-example-generic" data-slide-to="1"></li>
</ol> <!-- Wrapper for slides -->
<div class="carousel-inner">
<div class="item active">
<img src="https://tse4-mm.cn.bing.net/th/id/OIP._PbxAuEi3ce9S1DtQ3KilwHaEK?w=306&h=180&c=7&o=5&dpr=1.25&pid=1.7"
alt="...">
</div>
<div class="item">
<img src="https://tse2-mm.cn.bing.net/th/id/OIP.Det5e8us-qsNAGEhnL6u0AHaF7?w=238&h=190&c=7&o=5&dpr=1.25&pid=1.7"
alt="...">
</div>
</div> <!-- Controls -->
<a class="left carousel-control" href="#carousel-example-generic" role="button" data-slide="prev">
<span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="right carousel-control" href="#carousel-example-generic" role="button" data-slide="next">
<span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
</div> </div> </div> </body> </html>

index.html

<!DOCTYPE html>
<html lang="en"> <head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src='https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js'></script>
<link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css'
integrity='sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u' crossorigin='anonymous'>
<script src='https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js'
integrity='sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa'
crossorigin='anonymous'></script> <style>
body {
display: flex;
justify-content: center;
align-self: center;
height: 100vh;
background-color: rebeccapurple; } form.form1 {
display: flex;
flex-flow: column;
justify-content: center;
align-self: center;
border: 1px solid #ddd;
padding: 10px;
width: 30%;
background-color: white;
border-radius: 15px;
}
</style> </head> <body> <form class="form1" action="#">
<div class="form-group">
<label for="exampleInputEmail1">username</label>
<input type="email" class="form-control" id="exampleInputEmail1" placeholder="please enter user name">
</div>
<div class="form-group">
<label for="exampleInputPassword1">Password</label>
<input type="password" class="form-control" id="exampleInputPassword1"
placeholder="please enter user password">
</div> <button type="submit" class="btn btn-default" disabled>Submit</button>
</form> </body> </html>

login.html

   除此之外,还要将视图中index函数与login函数的返回结果改一下

# view.py

def index(request):
with open(file="template/index.html",mode="r",encoding="utf-8") as f:
res = f.read()
return res def login(request):
with open(file="template/login.html",mode="r",encoding="utf-8") as f:
res = f.read()
return res def error(request):
return "404 Resource request error"

view.py

   那么目前,我们的框架已经初具雏形了,能够根据请求路径的不同返回不同的HTML文档。

pymsql

   继续接着做逻辑,点击login后输入用户名和密码提交完应该对数据库进行验证,判断该用户是否存在。

   那么现在我们就需要用到pymysql模块了,还是新建一个文件夹叫db,然后创建db文件进行操作。

import pymysql

class DbServer(object):
def __init__(self):
self.conn = pymysql.connect(
host="localhost",
database="db1",
charset="utf8mb4",
user="root",
cursorclass=pymysql.cursors.DictCursor, # 记录结果,字典显示
autocommit=True, # 自动提交
) self.cursor = self.conn.cursor() def select(self, sql, val=None):
res = self.cursor.execute(sql, val)
return res, self.cursor.fetchone() # 返回查找行数,查找结果 def insert(self, sql, val=None):
pass def drop(self, sql, val=None):
pass def deletle(self, sql, val=None):
pass def __del__(self):
# 关闭程序前关闭链接与游标
self.cursor.close()
self.conn.close() if __name__ != '__main__': # 不能当作独立文件进行运行
dbserver = DbServer()

db.py

   记得在数据库中先插入数据

create table user(
id INT PRIMARY KEY AUTO_INCREMENT,
name CHAR(12) NOT NULL,
password CHAR(12) NOT NULL,
INDEX(name) -- 添加索引
); INSERT INTO user(name,password) VALUES
("Yunya","");

MySQL命令

   别忘了在view.py中进行导入,与此同时,还要写一个验证功能。

from db.db import dbserver
import jinja2 def index(request):
with open(file="template/index.html", mode="r", encoding="utf-8") as f:
res = f.read()
return res def login(request):
with open(file="template/login.html", mode="r", encoding="utf-8") as f:
res = f.read()
return res def login_verif(request):
# GET 请求 QUERY_STRING
request_msg = request.get("QUERY_STRING", None).split("&")
user_dict = {} for msg in request_msg:
key, value = msg.split("=")
user_dict[key] = value
from db.db import dbserver def index(request):
with open(file="template/index.html", mode="r", encoding="utf-8") as f:
res = f.read()
return res def login(request):
with open(file="template/login.html", mode="r", encoding="utf-8") as f:
res = f.read()
return res def login_verif(request):
# GET 请求 QUERY_STRING
request_msg = request.get("QUERY_STRING", None).split("&")
user_dict = {} for msg in request_msg:
key, value = msg.split("=")
user_dict[key] = value sql = "select * from user where name=%s and password = %s"
val = (user_dict.get("username"), user_dict.get("password"))
result = dbserver.select(sql, val)
if result[0]:
return "Welcome" + result[1].get("name")
else:
return "Login failed, no such user" def error(request):
return "404 Resource request error"

view.py

   还要在urls.py文件中增加验证的路由解析。

from view.view import *

urls = [
("/index", index),
("/login", login),
("/login_verif", login_verif),
]

urls.py

   最后一步修改前端login.html中的form提交路径

  <form class="form1" action="http://127.0.0.1:8080/login_verif">
<div class="form-group">
<label for="username">username</label>
<input type="text" id="username" name="username" class="form-control" placeholder="please enter user name">
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" id="password" name="password" class="form-control"
placeholder="please enter user password">
</div> <button type="submit" class="btn btn-default">Submit</button>
</form>

login.html

jinja2

   在验证完成后,我们应该根据用户名与密码是否正确来返回不同的内容。

   这个时候可以使用jinja2的模板语言了。

   首先在Template文件夹下新建一个verification.html做验证

   然后修改一下view中的login_verif代码

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body> <div class="container"> <div class="row">
<div class="col-xs-6 col-sm-6 col-md-6 col-lg-6 col-xs-offset-3 col-sm-offset-3 col-md-offset-3 col-lg-offset-3 ">
<div class="page-header">
{% if login_msg.status %}
<h1>欢迎回家{{login_msg.username}}</h1>
{% else %}
<h1>无此用户!请检查用户名或密码是否输入正确</h1>
{% endif %}
</div>
</div>
</div> </div> </body>
</html>

verification.html

def login_verif(request):
# GET 请求 QUERY_STRING
request_msg = request.get("QUERY_STRING", None).split("&")
user_dict = {} for msg in request_msg:
key, value = msg.split("=")
user_dict[key] = value sql = "select * from user where name=%s and password = %s"
val = (user_dict.get("username"), user_dict.get("password"))
result = dbserver.select(sql, val) with open("./template/verification.html","r",encoding="utf-8") as f:
data = f.read() tmp = jinja2.Template(data) # 做成模板 if result[0]:
msg = {"username":result[1].get("name"),"status":1} else:
msg = {"username":None,"status":0} res = tmp.render(login_msg=msg) # 模板中添加变量
return res

view.py def login_verif

成果演示

代码总和

   db - db.py

import pymysql

class DbServer(object):
def __init__(self):
self.conn = pymysql.connect(
host="localhost",
database="db1",
charset="utf8mb4",
user="root",
cursorclass=pymysql.cursors.DictCursor, # 记录结果,字典显示
autocommit=True, # 自动提交
) self.cursor = self.conn.cursor() def select(self, sql, val=None):
res = self.cursor.execute(sql, val)
return res, self.cursor.fetchone() # 返回查找行数,查找结果 def insert(self, sql, val=None):
pass def drop(self, sql, val=None):
pass def deletle(self, sql, val=None):
pass def __del__(self):
# 关闭程序前关闭链接与游标
self.cursor.close()
self.conn.close() if __name__ != '__main__':
dbserver = DbServer()

   template - index.html

<!DOCTYPE html>
<html lang="en"> <head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src='https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js'></script>
<link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css'
integrity='sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u' crossorigin='anonymous'>
<script src='https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js'
integrity='sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa'
crossorigin='anonymous'></script>
<title>Document</title>
<style> .carousel .item {
height: 400px;
background-color: #777;
} .carousel-inner>.item>img {
position: absolute;
top: 0;
left: 0;
min-width: 100%;
height: 100%;
}
</style>
</head> <body> <nav class="navbar navbar-inverse">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">INDEX</a>
</div> <!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<form class="navbar-form navbar-left">
<div class="form-group">
<input type="text" class="form-control" placeholder="Search">
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
<ul class="nav navbar-nav navbar-right">
<li><a href="HTTP://127.0.0.1:8080/login">LOGIN</a></li>
<li><a href="#">REGISTER</a></li>
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav> <div class="container-fluid"> <div class="row">
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12 input-lg-5g bg-primar ">
<div class="page-header">
<h1>Example page header <small>Subtext for header</small></h1>
</div>
</div> <div class="col-xs-3 col-sm-3 col-md-3 col-lg-3">
<div class="list-group">
<a href="#" class="list-group-item active">
Cras justo odio
</a>
<a href="#" class="list-group-item">Dapibus ac facilisis in</a>
<a href="#" class="list-group-item">Morbi leo risus</a>
<a href="#" class="list-group-item">Porta ac consectetur ac</a>
<a href="#" class="list-group-item">Vestibulum at eros</a>
</div>
</div> <div class="col-xs-9 col-sm-9 col-md-9 col-lg-9">
<div id="carousel-example-generic" class="carousel slide" data-ride="carousel">
<!-- Indicators -->
<ol class="carousel-indicators">
<li data-target="#carousel-example-generic" data-slide-to="0" class="active"></li>
<li data-target="#carousel-example-generic" data-slide-to="1"></li>
</ol> <!-- Wrapper for slides -->
<div class="carousel-inner">
<div class="item active">
<img src="https://tse4-mm.cn.bing.net/th/id/OIP._PbxAuEi3ce9S1DtQ3KilwHaEK?w=306&h=180&c=7&o=5&dpr=1.25&pid=1.7"
alt="...">
</div>
<div class="item">
<img src="https://tse2-mm.cn.bing.net/th/id/OIP.Det5e8us-qsNAGEhnL6u0AHaF7?w=238&h=190&c=7&o=5&dpr=1.25&pid=1.7"
alt="...">
</div>
</div> <!-- Controls -->
<a class="left carousel-control" href="#carousel-example-generic" role="button" data-slide="prev">
<span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="right carousel-control" href="#carousel-example-generic" role="button" data-slide="next">
<span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
</div> </div> </div> </body> </html>

   template - login.html

<!DOCTYPE html>
<html lang="en"> <head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src='https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js'></script>
<link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css'
integrity='sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u' crossorigin='anonymous'>
<script src='https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js'
integrity='sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa'
crossorigin='anonymous'></script> <style>
body {
display: flex;
justify-content: center;
align-self: center;
height: 100vh;
background-color: rebeccapurple; } form.form1 {
display: flex;
flex-flow: column;
justify-content: center;
align-self: center;
border: 1px solid #ddd;
padding: 10px;
width: 30%;
background-color: white;
border-radius: 15px;
}
</style> </head> <body> <form class="form1" action="http://127.0.0.1:8080/login_verif">
<div class="form-group">
<label for="username">username</label>
<input type="text" id="username" name="username" class="form-control" placeholder="please enter user name">
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" id="password" name="password" class="form-control"
placeholder="please enter user password">
</div> <button type="submit" class="btn btn-default">Submit</button>
</form> </body> </html>

   template - verifcation.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body> <div class="container"> <div class="row">
<div class="col-xs-6 col-sm-6 col-md-6 col-lg-6 col-xs-offset-3 col-sm-offset-3 col-md-offset-3 col-lg-offset-3 ">
<div class="page-header">
{% if login_msg.status %}
<h1>欢迎回家{{login_msg.username}}</h1>
{% else %}
<h1>无此用户!请检查用户名或密码是否输入正确</h1>
{% endif %}
</div>
</div>
</div> </div> </body>
</html>

   urls - urls.py

from view.view import *

urls = [
("/index", index),
("/login", login),
("/login_verif", login_verif),
]

   view - view.py

from db.db import dbserver
import jinja2 def index(request):
with open(file="template/index.html", mode="r", encoding="utf-8") as f:
res = f.read()
return res def login(request):
with open(file="template/login.html", mode="r", encoding="utf-8") as f:
res = f.read()
return res def login_verif(request):
# GET 请求 QUERY_STRING
request_msg = request.get("QUERY_STRING", None).split("&")
user_dict = {} for msg in request_msg:
key, value = msg.split("=")
user_dict[key] = value
from db.db import dbserver def index(request):
with open(file="template/index.html", mode="r", encoding="utf-8") as f:
res = f.read()
return res def login(request):
with open(file="template/login.html", mode="r", encoding="utf-8") as f:
res = f.read()
return res def login_verif(request):
# GET 请求 QUERY_STRING
request_msg = request.get("QUERY_STRING", None).split("&")
user_dict = {} for msg in request_msg:
key, value = msg.split("=")
user_dict[key] = value sql = "select * from user where name=%s and password = %s"
val = (user_dict.get("username"), user_dict.get("password"))
result = dbserver.select(sql, val) with open("./template/verification.html","r",encoding="utf-8") as f:
data = f.read() tmp = jinja2.Template(data) if result[0]:
msg = {"username":result[1].get("name"),"status":1} else:
msg = {"username":None,"status":0} res = tmp.render(login_msg=msg) # 返回登录信息
return res def error(request):
return "404 Resource request error"

   run.py

from wsgiref.simple_server import make_server
from urls.urls import * def run(request, response): """
request:① 请求相关的所有数据
response:② 响应相关的数据
return:③ 返回给浏览器的数据
""" response("200 OK",[]) # 响应首行,响应头
func = None
request_path = request.get("PATH_INFO") # 拿到路径 for url in urls:
if request_path == url[0]:
func = url[1]
break # 匹配到后结束for循环 if func:
res = func(request)
else:
res = error(request) return [res.encode("utf-8")] if __name__ == '__main__':
server = make_server("localhost", 8080, run)
# ③ 实时监听127.0.0.1:8080地址,只要有链接请求,都交给run函数处理
server.serve_forever() # ④ 开启服务

最后结论

   其实通过这三个基础模块,相信你已经了解了其基本的流程,但是用这三个模块来做成一个建议的Web框架还是存在大量的不足。

   1.HTML文件代码冗余过度

   2.提交全部为GET方式,这使得密码等传输极度不安全

   3.原生SQL语句操纵数据库,开发效率偏低

   4.路由的URL解析太过死板,不能灵活解析

   这些不足点在Django框架中都会有非常好的解决方案,因此Django框架是学习PythonWeb的首选。

   总之前后端交互的大体流程就是这样,前端给请求路径,后端根据路径查询数据库中数据并进行处理后返回HTML文档再由模板语言进行解析(前后端不分离),最终呈现出一个完整的动态页面。

   当然还有很多知识点没有涉及到,如cookieajax,权限管理等等,这些都会在之后慢慢做介绍。

Python 利用三个简易模块熟悉前后端交互流程的更多相关文章

  1. Python Flask高级编程之RESTFul API前后端分离精讲 (网盘免费分享)

    Python Flask高级编程之RESTFul API前后端分离精讲 (免费分享)  点击链接或搜索QQ号直接加群获取其它资料: 链接:https://pan.baidu.com/s/12eKrJK ...

  2. Vue-CLI项目-axios模块前后端交互(类似ajax提交)

    08.31自我总结 Vue-CLI项目-axios前后端交互 一.模块的安装 npm install axios --save #--save可以不用写 二.配置main.js import axio ...

  3. 三、vue前后端交互(轻松入门vue)

    轻松入门vue系列 Vue前后端交互 六.Vue前后端交互 1. 前后端交互模式 2. Promise的相关概念和用法 Promise基本用法 then参数中的函数返回值 基于Promise处理多个A ...

  4. Servlet实现前后端交互的原理及过程解析

    在日常调试项目时,总是利用tomcat去启动项目,并进行前后端联调,但对于前后端的请求响应的交互原理及过程并不是特别清晰. 为什么在前端发出相应请求,就能跳转到后端通过程序得到结果再响应到前端页面呢? ...

  5. Node之简单的前后端交互

    node是前端必学的一门技能,我们都知道node是用的js做后端,在学习node之前我们有必要明白node是如何实现前后端交互的. 这里写了一个简单的通过原生ajax与node实现的一个交互,刚刚学n ...

  6. Django之META与前后端交互

    Django之META与前后端交互 1 提交表单之GET 前端提交数据与发送 1)提交表单数据 2)提交JSON数据 后端的数据接收与响应 1)接收GET请求数据 2)接收POST请求数据 3)响应请 ...

  7. 微信小程序 + thinkjs + mongoDB 实现简单的前后端交互

    说明:这段时间跟老师学习了一下mongodb数据库,这次也是第一次搭建后台服务,出了不少差错,特此来复盘一下,非常感谢对我提供帮助的同学~ 一.使用 thinkjs + mongodb 创建后台服务 ...

  8. Node.js实现前后端交互——用户注册

    我之前写过一篇关于使用Node.js作为后端实现用户登陆的功能,现在再写一下node.js做后端实现简单的用户注册实例吧.另外需要说的是,上次有大佬提醒需要加密数据传输,不应该使用明文传输用户信息.在 ...

  9. 【开源.NET】 轻量级内容管理框架Grissom.CMS(第二篇前后端交互数据结构分析)

    这是 CMS 框架系列文章的第二篇,第一篇开源了该框架的代码和简要介绍了框架的目的.作用和思想,这篇主要解析如何把sql 转成标准 xml 配置文件和把前端post的增删改数据规范成方便后台解析的结构 ...

随机推荐

  1. [问题记录] webpack devServer HtmlWebpackPlugin 没有加载 js、css

    webpack devServer 没有加载 js.css HtmlWebpackPlugin runtimeChunks 注入问题. 描述 写了一个极其简单的多页面 demo 启动开发服务器,发现样 ...

  2. Mac 系统更新怎么忽略

    1.在“终端”命令行中输入以下命令: sudo softwareupdate --ignore “macOS Catalina” 2.按回车键,然后输入管理员密码*,然后再次按回车键,以超级用户权限执 ...

  3. 2020-07-20:你觉得redis有什么缺点,给你改进的话你会怎么改进?

    福哥答案2020-07-20: 1.由于 Redis 是内存数据库,短时间内大量增加数据,可能导致内存不够用.2.redis是单线程的,单台服务器无法充分利用多核服务器的CPU.3.遇到大量查询时容易 ...

  4. 2020-04-24:Object obj = new Object()这句话在内存里占用了多少内存

    福哥答案2020-04-25:这道题最好把对象和变量分开说明,否则容易产生误解.以下都是64位环境下.针对对象:压缩状态:MarkWord 8+klass 4+数据0+对齐4=16非压缩状态:Mark ...

  5. Filebeat 收集K8S 日志,生产环境实践

    根据生产环境要求,需要采集K8Spod 日志,和开发协商之后,pod中应用会将日志输出到容器终端上,这时可以直接用filebeat 采集node节点上面的/var/log/containers/*.l ...

  6. Homekit_Dohome_智能插座

    简介: 本款智能插座有三个版本可供选择,分别为Homekit版本,涂鸦版本,Dohome版本,各个版本的区别如下: DoHome版特点: 支持HomeKit 支持Amazon 支持Google ...

  7. LeetCode 120. Triangle (三角形最小路径和)详解

    题目详情 给定一个三角形,找出自顶向下的最小路径和.每一步只能移动到下一行中相邻的结点上. 例如,给定三角形: [ [2], [3,4], [6,5,7], [4,1,8,3] ] 自顶向下的最小路径 ...

  8. 01 Arduino-点亮一盏LED灯

    01 硬件连接  图片比较丑 特别说明:一般默认为二极管灯的压降是 2V 均值电流为15ma,所以如果接在5V的电源上面,串联接的电阻值为200欧姆左右,可做适当调整 切记不允许把LED灯直接并联在5 ...

  9. Revit二次开发——非模态窗口的事件处理

    一.起因    自己在写revit二开时,有一个Winform窗体按钮点击事件需要 触发调用事务进行处理,结果出现“异常“Starting a transaction from an external ...

  10. Disruptor极速队列

    参考:http://www.cnblogs.com/haiq/p/4112689.html Disruptor 是线程内通信框架,用于线程里共享数据.LMAX 创建Disruptor作为可靠消息架构的 ...