上传文件
- 前端通过表单发送post请求
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>upload file</title>
</head>
<body>
<form action="/files" method="post" enctype="multipart/form-data">
<input type="file" name="上传图片"> <br>
<input type="submit" value="upload">
</form>
</body>
</html>
- flask后端通过request.files 接收
from werkzeug.utils import secure_filename # 避免文件名被伪造
@app.route("/files", methods=["POST", "GET"])
def upload_file():
if request.method == "GET":
return render_template("upload_file.html")
elif request.method == "POST":
print(request.files)
# 获取数据
img = request.files["上传图片"]
# 文件对象保存在media目录下
img.save(f"media/{secure_file(img.filename)}") # 不要以/开头
return "upload ok"
else:
return "404"
会话保持
- cookie
- 在客户端浏览器中以key-val形式存储用户的信息,发送请求时传给服务端,完成对用户的身份认证;
- request.cookies.get(key) 获取客户端的cookie信息
- response.set_cookie(key, value, max_expire=3600) 设置cookie
- session
- 在flask中session是一个请求上下文对象(类字典),基于cookie来存储用户的数据
- 需要app.SECRET_KEY 对用户的数据加密后,存储在客户端浏览器中的cookie中。若要将用户数据存储在服务端,可以使用flask-session等扩展库;
- 命令行下生成密钥
$ python -c 'import secrets; print(secrets.token_hex())'
'192b9bdd22ab9ed4d12e236c78afcb9a393ec15f71bbf5dc987d54727823bcbf'
响应
视图函数
- 视图函数处理请求,并返回数据
- 若返回Response对象,则flask直接返回该对象;
- 若返回str,则flask将str数据封装为Response对象;
- 若返回list/dict,则flask调用jsonify封装为json的响应对象;
- 若返回tuple,则tuple的格式为(response, status), (response, headers), or (response, status, headers),status为状态码(如404),headers为额外的响应头(list/dict);
- 在视图中自己创建响应对象
- from flask import Response, make_response, jsonify
# 创建响应对象
res = Response("xx", content_type="text/html", status=200)
res2 = make_response("my response", 200)
res2.status_code = 301 # 覆盖200
res2.content_type = "text/plain"
res2.headers["sign"] = "laufing"
# json响应
res3 = jsonify({"name": "jack"})
redirect重定向 与 abort
from flask import abort, redirect, url_for
@app.route('/')
def index():
return redirect(url_for('login')) # 将当前请求重新定向到另一个endpoint
@app.route('/login')
def login():
abort(401) # 提前返回错误信息
this_is_never_executed()
# 自定义错误码的响应
# 更多参考 https://flask.palletsprojects.com/zh-cn/stable/errorhandling/
@app.errorhandler(404)
def page_not_found(error):
# 返回自定义的404页面
return render_template('page_not_found.html'), 404
flask-cors
全局配置跨域
# 安装
pip install flask-cors -i https://pypi.tuna.tsinghua.edu.cn/simple/
# 使用
from flask_cors import CORS
if __name__ == "__main__":
CORS(app, supports_credentials=True, origins=["xx",])
app.run(host="", port=5000, debug=True)
其他参数
局部跨域,针对特定的API
# 局部跨域
from flask_cors import cross_origin
# 如下,只允许/test跨域
@app.route("/test", methods=['GET'])
@cross_origin()
def test():
return jsonify({"name": "laufing"})
装饰器中的参数与CORS一致。
配置响应头的跨域
# 需要接收OPTIONS请求
@app.route("/send_mail", methods=["GET", "POST", "OPTIONS"])
def send_mail():
res = jsonify({"code": 200, "msg": "发送邮件成功"})
res.headers["Access-Control-Allow-Origin"] = "http://localhost:8080"
res.headers["Access-Control-Allow-Credentials"] = "true"
res.headers["Access-Control-Allow-Headers"] = "x-requested-with, authorization, token, content-type"
return res