web框架

框架:framework,特指为解决一个开放性问题而设计的具有一定约束性的支撑结构,使用框架可以帮你快速开发特定的系统,简单地说,就是你用别人搭建好的舞台来做表演

对于所有的web框架,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端


  • 最简单的Web应用就是先把HTML用文件保存好,用一个现成的HTTP服务器软件,接收用户请求,从文件中读取HTML,返回
  • 如果要动态生成HTML,就需要把上述步骤自己来实现。不过,接受HTTP请求、解析HTTP请求、发送HTTP响应都是苦力活,如果我们自己来写这些底层代码,还没开始写动态HTML呢,就得花个把月去读HTTP规范
  • 正确的做法是底层代码由专门的服务器软件实现,我们用Python专注于生成HTML文档。因为我们不希望接触到TCP连接、HTTP原始请求和响应格式,所以,需要一个统一的接口,让我们专心用Python编写Web业务
  • 这个接口就是WSGI:Web Server Gateway Interface

from wsgiref.simple_server import make_server


def application(environ, start_response):
start_response('200 OK', [('Content-Type', 'text/html')])
return [b'<h1>Hello, web!</h1>']


httpd = make_server('', 8080, application)

print('Serving HTTP on port 8000...')
# 开始监听HTTP请求:
httpd.serve_forever()

  • framework
from wsgiref.simple_server import make_server
import time


def index_404():
f = open('dj_html/404.html', 'rb')
data = f.read()
return data


def foo_alex(req):

f = open('dj_html/about_alex.html', 'rb')
data = f.read()
return data


def foo_other(req):

f = open('dj_html/about_other.html', 'rb')
data = f.read()
return data


def login(req):

f = open('dj_html/login.html', 'rb')
data = f.read()
return data


def signup(req):
pass


def showtime(req):
now_time = time.asctime()
# return b'<h1>%s</h1>' % str(now_time).encode('utf8')

f = open('dj_html/showtime.html', 'rb')
data = f.read()
data = data.decode('utf8')
data = data.replace('@time@', str(now_time))
# data.replace('@time@', now_time)
return data.encode('utf8')


def router():
url_patterns = [
('/login', login),
('/signup', signup),
('/alex', foo_alex),
('/other', foo_other),
('/time', showtime),
]
return url_patterns


def application(environ, start_response):

path = environ['PATH_INFO']
start_response('200 ok', [('Content-Type', 'text/html')])
print('path', environ['PATH_INFO'])

url_patterns = router()

var_path = None
for item in url_patterns:
if item[0] == path:
var_path = item[1]
break

if var_path:
return [var_path(environ)]
else:
return [index_404()]

# if path == '/alex':
# return [foo_alex()]
# elif path == '/other':
# return [foo_other()]
# else:
# return [index_404()]

# return [b'<h1>Hello Web!</h1>']


httpd = make_server('', 8088, application)

print('Serving HTTP on port 8088...')
httpd.serve_forever()


  • about.alex
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>About</title>
</head>
<body>
<h1>Hello Alex</h1>
</body>
</html>


  • about.other
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>About</title>
</head>
<body>
<h1>hello other</h1>
</body>
</html>


  • login
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>login</title>
</head>
<body>
<form action="http://127.0.0.1:8088/alex" method="post">
<p><label for="username">用户名</label><input type="text" name="username" id="username"></p>
<p><label for="password">密码</label><input type="password" name="password" id="password"></p>
<p><input type="submit" name="login" id="login"></p>
</form>
</body>
</html>


  • 404
<!DOCTYPE html>
<html lang="zh">

<head>
<meta charset="utf-8">
<title>404</title>
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=0"/>
<style>
html,
body {
width: 100%;
height: 100%
}

a,
a img,
a:before,
a:after {
text-decoration: none;
transition-duration: .25s
}

section {
display: block
}

body {
line-height: 1
}

#about {
width: 40%;
position: absolute;
top: 40%;
left: 10%;
z-index: 20;
transform: translate(0, -50%);
}

#about h1 {
margin: 30px;
}

#about p {
margin: 30px;
}

#about img {
margin-left: 30px;
}

#about .social {
float: left;
margin: 30px;
}

#about .copyright {
width: 100%;
float: left;
margin-bottom: 0px;
}

@media (max-width: 768px) {
#about {
width: 100%;
left: 0px;
height: 100%;
background-color: rgba(255, 255, 255, 0.85);
}

#about h1 {
margin: 30px;
}

#about p {
margin: 30px;
}

#about .social {
margin: 30px;
}

#about .copyright {
width: 100%;
float: left;
margin-bottom: 0;
}
}

@media (max-width: 580px) {
#about {
width: 100%;
left: 0;
height: 100%;
background-color: rgba(255, 255, 255, 0.85);
}

#about h1 {
margin: 30px;
}

#about p {
margin: 30px;
margin-bottom: 0
}

#about .social {
margin: 30px;
margin-bottom: 0
}

#about .copyright {
width: 100%;
float: left;
margin-bottom: 0;
}
}

.animated {
animation-duration: 1s;
animation-fill-mode: both
}

.bounce-in {
animation-name: bounce-in
}

@keyframes bounce-in {
from,
60%,
75%,
90%,
to {
animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1)
}
0% {
opacity: 0;
transform: translate3d(-3000px, -50%, 0)
}
60% {
opacity: 1;
transform: translate3d(25px, -50%, 0)
}
75% {
transform: translate3d(-10px, -50%, 0)
}
90% {
transform: translate3d(5px, -50%, 0)
}
to {
transform: translate3d(0, -50%)
}
}

body {
font-family: "Roboto", sans-serif;
font-size: 16px;
font-weight: 300;
line-height: 1.75;
color: rgba(0, 0, 0, 0.65)
}

h1 {
font-family: "Merriweather", sans-serif;
font-size: 50px;
font-weight: 700;
line-height: 1.25;
color: rgba(0, 0, 0, 0.85);
margin-bottom: 25px
}

a {
color: rgba(3, 3, 3, 0.85);
font-weight: 600;
}

@media (max-width: 580px) {
body {
font-size: 14px
}

h1 {
font-size: 42px;
line-height: 1.45
}
}

.bg-align {
margin-top: 50%;
}
</style>
</head>
<body>
<section id="about" class="animated bounce-in">
<div class="bg-align">
<h1>404</h1>
<p>Oops! It looks like you're lost...</p>
<p>The Page you're looking for doesn't exist or another error occurred.</p>
</div>
</section>
</body>
</html>


  • showtime
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>时间</title>
</head>
<body>
<h1>时间: @time@</h1>
</body>
</html>

作者:Alice只敲代码不秃头