python 实现web应用

1.介绍http和html

html是编写网页的语言,编写的文件是html文件

http是传输协议

web网页的展示和使用会用到html、css、javascript

css是样式,html是内容 、javascript是网页的响应动作

静态网站和动态网站

静态网站就可以把写好的html文件放在服务器(apache nigix)上,发送不同的http请求得到对应的返回结果

动态网站:

页面数据会访问数据库,根据不同的逻辑触发显示不同页面样式及数据;静态网页是用html+css+js/ajax写的,用浏览器就可以打开但是动态网页,java的动态页面是用jsp写的,打开正常展示需要依赖web severlet,severlet执行调用数据库/调用后端接口等的请求,将返回的数据返回给jsp,jsp对数据进行包装生成html,返回给浏览器

(动态网页和静态网页的区别,参考文章:静态页面和动态页面的区别 - 小马夫 - 博客园

2,web应用的请求过程

1)浏览器发送一个http请求

2)服务器收到请求,生成一个html文档

3)服务器将这个html文档封装到http请求的响应体body返回给浏览器

4)浏览器从response中取出html并显示

  • 浏览器就是依靠Content-Type来判断响应的内容是网页还是图片
  • 浏览器显示html文档的过程就是渲染

(浏览器渲染的过程)

浏览器是怎么加载页面的?_wyy_a的博客-CSDN博客

 

3.python 语言生成html文档,依赖于统一的接口WSGI (Web Server Gateway Interface)

实现方法application,该方法有两个参数:environ是接口请求、start_response:一个发送http响应的函数

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

样例中的application方法中,没有对请求数据做处理,直接调用start_response方法,start_response方法接收两个参数,一个是r

esponse code,一个是response Header的list

return 语句将list中的内容作为response body体返回

WSGI接口需要一个WSGI服务器来调用,python写了一个WSGI的服务器是wsgiref

# server.py
# 从wsgiref模块导入:
from wsgiref.simple_server import make_server
# 导入我们自己编写的application函数:
from script.pythonweb import application


# 创建一个服务器,IP地址为空,端口是8000,处理函数是application:
httpd = make_server('', 8000, application)
print('Serving HTTP on port 8000...')
# 开始监听HTTP请求:
httpd.serve_forever()

首先启动WSGI服务器,然后,页面请求http://localhost:8000/,就可以在页面拿到刚才写的请求html内容 

4、python的web框架 -Flask 

一个web应用有很多的http请求,如果单纯使用WSGI去写,那代码会很难看

def application(environ, start_response):
method = environ['REQUEST_METHOD']
path = environ['PATH_INFO']
if method == 'GET' and path == '/':
return handle_home(environ, start_response)
if method == 'POST' and path == '/singin':
return handle_signin(environ, start_response)

在一个application方法中写很多的if,按照不同的接口调用不同的函数,返回不同的response

所以,我们需要依赖一个web框架,代码只写不同接口的处理函数

常用的框架有flask、Django

今天先学习的是flask框架

from flask import Flask
from flask import request

app = Flask(__name__)

@app.route('/', methods=['GET', 'POST'])
def home():
    return '<h1>Home</h1>'

@app.route('/signin', methods=['GET'])
def signin_form():
    return '''<form action="/signin" method="post">
              <p><input name="username"></p>
              <p><input name="password" type="password"></p>
              <p><button type="submit">Sign In</button></p>
              </form>'''

@app.route('/signin', methods=['POST'])
def signin():
    # 需要从request对象读取表单内容:
    if request.form['username']=='admin' and request.form['password']=='password':
        return '<h3>Hello, admin!</h3>'
    return '<h3>Bad username or password.</h3>'

if __name__ == '__main__':
    app.run()
  • 定义一个flask对象
  • 定义web的不同url的请求函数内容,不同接口对应什么逻辑
  • main方法中 调用flask对象的run方法

5.模板 MVC

从Flask的实现上来看,不同的接口只需要在body中填写对应的html文档内容,但是如果html很长编写接口就很冗余,也不好看,所以出现了模板,模板中定义的是一个带有变量的html文件,相当于MVC模型中的view

举例,模板文件form.html:

<html>
<head>
  <title>Please Sign In</title>
</head>
<body>
  {% if message %}
  <p style="color:red">{{ message }}</p>
  {% endif %}
  <form action="/signin" method="post">
    <legend>Please sign in:</legend>
    <p><input name="username" placeholder="Username" value="{{ username }}"></p>
    <p><input name="password" placeholder="Password" type="password"></p>
    <p><button type="submit">Sign In</button></p>
  </form>
</body>
</html>

        这个是登录页面及登录失败的模板文件,文件中有变量{{message }}、{{ username }},在执行html文件时就会将{{message }}、{{ username }}显示为变量message、username的值

@app.route('/signin', methods=['POST'])
def signin():
    username = request.form['username']
    password = request.form['password']
    if username=='admin' and password=='password':
        return render_template('signin-ok.html', username=username)
    return render_template('form.html', message='Bad username or password', username=username)

        登录方法中,登录失败,会调用模板form.html,message变量为'Bad username or password',变量username= 输入的username

        mvc模型:Model-View-Controller

        对于Flask web应用来说,接口url的函数是controller、模板html文件是view,model就是给模板传递变量的一个dict

上一篇:go 连接 mysql: could not use requested auth plugin ‘mysql_native_password‘


下一篇:多线程网络下载