flask使用

 

Python-web Flask框架项目打包成exe文件
Flask项目能打包为单个exe文件运行?掌握原理后居然如此简单!

配置

安装

pip install flask

运行

创建app.py文件

from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello():
    return 'Hello, World!'

if __name__ == '__main__':
    app.run(debug=True)
  • 默认5000端口
flask run

  • 指定地址端口
flask run --host=0.0.0.0 --port=9999
  • 终止进程
ps -aux | grep flask | grep -v grep | awk {'print $2'} | xargs kill -9

部署

设部署上面app.py文件

docker

from python:3.7-alpine
workdir /app
copy . .

run pip install -i https://pypi.tuna.tsinghua.edu.cn/simple/ Flask

cmd flask run --host=0.0.0.0 --port=5000

expose 5000

supervisor

  • supervisor.conf
[supervisord]
nodaemon=true

[program:app]
# 按自己路径修改
directory=/home/dmjcb/FlaskTest
command=flask run --host=0.0.0.0 --port=5000
# 按自己用户名修改
user=dmjcb
autostart=true
autorestart=true
  • 启动
supervisord -c supervisor.conf

uwsgi

  • uwsgi.ini
[uwsgi]
# 启动主进程, 来管理其他进程
master = true

# 地址和端口号
http = :5000

# app.py路径
wsgi-file = app.py

# uwsgi指定application, flask中为app
callable = app

# 开启的进程数量
processes = 2

# 运行线程
threads = 8

# 设置用于uwsgi包解析的内部缓存区大小为64k.默认是4k
buffer-size = 32768
uwsgi uwsgi.ini

pyinstaller

pip install pyinstaller -i https://pypi.doubanio.com/simple
  • 方法一
pyinstaller -F -i --add-data="./static;./static" --add-data="./templates;./templates" app.py

dist 目录下会生成可执行文件

  • 方法二
pyinstaller -F app.py

将static 与templates 目录复制到dist目录下

修改.spec

datas=[('./static', 'static'), ('./templates', 'templates')], 
pyinstaller -F *.spec

模块

表单

前端

<form action="{{ url_for('main_page')}}" method='POST'>
    <input type="text" class="form-control" id="name" name="name" required />
    <input type="datetime-local" class="form-control" id="time" name="time" />
    <select class="form-control" name="identify">
        <option value="水务类">水务类</option>
        <option value="工程消费类">工程消费类</option>
        <option value="卫生健康类">卫生健康类</option>
    </select>
        
    <input type="submit" class="btn btn-success" value="开始抽签"></input>
    <input type="reset" class="btn btn-danger" value="清空"></input>
</form>

后端

@app.route('/main', methods=['GET', 'POST'])
def main_page():
    if request.method == 'GET':
        return render_template('main.html')
    if request.method == 'POST':
        # 获取表单值
        name = request.form.get("name")
        time = request.form.get("time")
        identify= request.form.get("identify")
        # 转为dict
        data = request.form.to_dict()
        return render_template('main.html', data=data)

返回静态文件

url_for

<link rel="stylesheet" href="{{ url_for('static', filename='bootstrap.min.css') }}">
<script src="{{ url_for('static', filename='jquery.min.js') }}"></script>

send_from_directory

send_from_directory('文件目录', 文件名)
from flask import Flask, send_from_directory

app = Flask(__name__)

@app.route('/<path>')
def get_image(path):
    return send_from_directory('static', path)

if __name__ == '__main__':
    app.run(debug=True)

图片路径为/static/head.jpg, 访问127.0.0.1:5000/head.jpg即返回静态文件

问题

跨域

前端使用 XMLHttpRequest 发送 GET 请求时, 后端 Flask已收到请求, 但前端无法显示返回值

  • 前端
<!DOCTYPE html>
<html>
    <head>
    <meta charset="utf-8" />
    <script>
        function loadXMLDoc() {
            var xmlhttp
            if (window.XMLHttpRequest) {
                // IE7+, Firefox, Chrome, Opera, Safari 浏览器执行代码
                xmlhttp = new XMLHttpRequest()
            } else {
                // IE6, IE5 浏览器执行代码
                xmlhttp = new ActiveXObject("Microsoft.XMLHTTP")
            }
            xmlhttp.onreadystatechange = function () {
                if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                    const v = xmlhttp.responseText
                    alert(v)
                }
            }
            xmlhttp.open("GET", "http://127.0.0.1:5000/", true)
            xmlhttp.send()
        }
    </script>
    </head>
    <body>
        <button type="button" onclick="loadXMLDoc()">获取内容</button>
    </body>
</html>
  • 后端
from flask import Flask

app = Flask(__name__)

@app.route('/', methods=['GET', 'POST'])
def hello_world():
    return 'HELLO'

if __name__ == '__main__':
    app.run()

分析

使用 F12 进入控制台后发现错误如下

Access to XMLHttpRequest at 'http://127.0.0.1:5000/' from origin ajax.html:1 'null' has been blocked by CORS poily: NO 'Access-Control-Allow-Origin' header is present on the requested resource

GET http://127.0.0.1:5000/ net::ERR_FAILED

通过查询此为跨域问题, 所以需设置Flask允许跨域

解决

Flask 配 Cors 跨域, 使用 flask-cors 包, 并有两种方式

方式 范围 特点
@cross_origin 装饰器 单个路由 适用于配置特定API 接口
CORS 函数 配置全局 API 接口 适用于全局API 接口配置
pip install flask-cors
# 后端代码修改为
from flask import Flask
from flask_cors import cross_origin

app = Flask(__name__)

@app.route('/', methods=['GET', 'POST'])
@cross_origin()
def hello_world():
    return 'HELLO'

if __name__ == '__main__':
    app.run()