2.2.2 Requests对象
from flask import request
request主要的属性
”http://127.0.0.1/hello?name=Grey"
path http路径名称 ‘hello"
fullpath 全路径 ”/hello?name=Grey"
host "127.0.0.1"
host_url "http://127.0.0.1"
base_url "http://127.0.0.1/hello"
url ”http://127.0.0.1/hello?name=Grey"
url_root "http://127.0.0.1"
args Werkzeug的ImmutableMulyiDict对象 存储解析后的查询字符串,可通过字典方式获取.如果你想获取未解析的原生字符串,可以使用query_string属性
blueprint 当前蓝图的名称
cookies 一个包含有所有随请求提交的cookies的字典
data 一个字符串形式的请求数据
endpoint 与当前请求相匹配的端点值
files Werkzeug的MultiDict对象 包含所有上传文件 可以使用字典的形式获取文件 使用的键为文件input标签的name属性值 对应的值为Werkzeug的FileStorge对象,可以调用save()方法传入保存路径来保存文件
form Werkzeug 的ImmutableMutilDict对象 与files类似 包含解析后的表单数据 表单字段值通过input的name属性值最为键获取
values Werkzrug的CombinedMultiDict对象 结合了args和form属性的值
get_data(cache=True, as_text=False, parse_form_data=Fasle)
get_json(self, force=False, silent=Fasle, cache=True)
headers 一个Werkzeug的EnvironHeaders对象 包含首部字段 可以通过字典的形式操作
is_json 包含MIME类型判断是否为json数据 返回bool值
json 包含解析后的json数据 内部调用get_json()方法 可通过字典的形式获取键值
method 请求的HTTP方法
referer 请求发起的URL
schema 请求的URL模式(http or https)
user_agent 用户代理 包含了用户的客户端类型 操作系统等信息
from flask import Flask, request
app = Flask(__name__)
@app.route("/")
def index():
name = request.args.get("name", "Flask")
return "<h1>Hello, %s!</h1>" % name
2.2.3 在Flask中处理请求
1.路由匹配
$ flask routes
显示所有端点值 请求方法 和 路由规则
设置监听的HTTP方法
@app.route("/hello", methods=["GET", "POST"]
def hello():
return "hello flask"
3.URL处理
string 不包含斜线的字符串
int 整型
float 浮点数
path 包含斜线的字符串
any 匹配一系列给定值中的一个元素
uuid UUID字符串
@app.route("/goback/<int:year>")
def go_back(year):
return "<p>Welcome to %d</p>" % year
4.请求钩子
before_first_request 注册一个函数 在处理第一个请求前运行
before_request 注册一个函数 在处理每个请求前运行
after_request 注册一个函数 如果没有未处理的一次抛出 会在每个请求结束后运行
teardown_request 注册一个函数 即使有未处理的异常抛出 会在每个请求结束后运行 如果发生异常 会传入异常对象作为参数到注册的函数中
after_this_request 在师徒函数内注册一个函数 会在这个请求结束后运行
2.3 HTTP响应
在Flask中生成响应
@app.route("/hello")
def hello():
...
return "", 302, ("Location", "http://www.example.com")
1.重定向
from flask import redirect
@app.route("/hello")
def hello():
return redirect("http://www.example.com")
使用redirect时 默认的状态码为302 如果想修改状态码 可以在redirect()函数中作为第二个参数或使用code关键字传入
定义到其他视图
redirect(url_for("hello"))
2.错误与响应
from flask import Flask, abort
app.route("/404")
def not_found():
abort(404)
3.响应格式
Content-Type: text/html; charset=utf-8
from flask import make_response
app.route("/foo")
def foo():
response = make_response("Hello, World") # 创建Response实例
response.mimetype = "text/plain"
return response
2.3.3
Response类的常用属性和方法
headers 一个Werkzeug的Headers对象 表示响应手部;可以像字典一样操作
status 状态码, 文本类型
status_code 状态码,整型
mimetype Mime类型(仅包含内容类型部分)
set_cookie() 用来设置一个cookie
set_cookie的参数
key cookie的键
value cookie的值
max_age cookie被保存的时间数,单位为秒,默认在用户会话结束 即关闭浏览器时过期
expires 具体的过期时间 传入的值为一个datetime对象 或Unix时间戳
path 限制cookie只在给定的路径可用 默认为整个域名
domain 设置cookie可用的域名
secure 如果设为True, 只有通过https才可以使用
httponly 如果设为True, 进制客户端javascript获取cookie
@app.route("/set/<name>")
def set_cookie(name):
response = make_response(redirect(url_for("hello")))
response.set_cookie("name", name)
return response
2.4 session
app.secret_key = “secret string"
或者在.env
SECRET_KEY=secret string
然后在程序内通过os模块提供的os提供的getenv方法获取
import os
app.secret_key = os.getenv("SECRET_KEY", "secret string")
# 用户认证
from flask import redirect, session, url_for
@app.route("/login")
def login():
session["login_in"] = True #写入session
return redirect(url_for("hello"))
# 模拟管理后台
from flask import session, abort
@app.route("/login")
def admin():
if "login_in" not in session:
abort(403)
return "Welcome to admin page"
# 登出用户
app.route("logout")
def logout():
if "login_in" in session:
session.pop("login_in")
return redirect(url_for("hello"))
2.4 Flask上下文
flask中的上下文变量
变量名 上下文类别 说明
current_app 程序上下文 指向处理请求的当前程序实例
g 程序上下文 替代python的全局变量用法, 确保仅在 当前请求中可用 。用于存储全局数据 每次请求都会重设
request 请求上下文 封装客户端发出的请求报文数据
session 请求上下文 用于记住请求之间的数据 通过签名的Cookie实现
from flask import g
@app.before_request
def get_name():
g.name = request.args.get("name")
# 通过设置这个钩子 可以在其他视图直接使用g。name获取对应的值 另外g也支持使用类似字典的get(), pop()以及setdefault()方法进行操作
2.4.2
在以下情况 flask 会自动帮我们激活程序上下文:
当我们使用flask run命令启动程序时
使用旧的app.run()方法启动程序时
执行使用@app.cli.command()装饰器的flask命令时
使用flask shell命令启动python shell时
当请求进入时, Flask会自动激活请求上下文.这时我们可以使用request和session变量.
另外 当请求上下文被激活时 程序上下文也被自动激活 。当请求处理完毕后 ,请求上下文和程序上下文也会被自动摧毁 也就是说 在请求处理时这两者拥有相同的生命周期。
同样依赖于上下文的还有url_for, jsonify
使用flask shell 可以使用current_app和g变量, 也可以手动激活请求上下文来激活request
>>from app import app
>>from flask import current_app
>>with app.app_content():
current_app.name
>>"app"
或者显示的使用push()方法激活上下文,在执行完相关操作时使用pop()方法销毁上下文:
>>from app import app
>>from flask import current_app
>>app_ctx = app.app_content()
>>app_ctx.push() # 激活上下文
>>current_app.name
"app"
>>app_ctx.pop() # 摧毁上下文
# 请求上下文则可以通过test_request_content()方法临时创建
>>from app import app
>>from flask import request
>>with app.test_request_context("/hello"):# 零时创建请求上下文
request.method
"GET"
2.4.3 上下文钩子
Flask也为上下文提供了一个teardown_appcontext钩子,使用它注册的回调函数会在程序上下文被销毁时调用,而且通车会在请求上下文被摧毁时调用 比如 你需要在每个请求处理结束后销毁数据库连接:
@app.teardown_appcontext
def teardown_db(execption):
...
db.close()
使用app.teardown_appcontext装饰器注册的回调函数 需要接收异常对象作为参数 当请求被正常处理这个参数为None 这个函数的返回这将被忽略
上下文是Flask重要的话题 后续我们将详细了解上下文的实现原理
2.5 HTTP进阶实践
2.5.1
重定向回上一个页面
request.referer获取之前的页面
redirect(request.referer or url_for("hello") # 可能referer为None
# 除了自动从referer获取 另一种更为常见的方式是在URL中手动加入包行当前页面URL的查询参数
@app.route("/foo")
def foo():
return "<a href="%s"></a>" % url_for("do_something", next=request.full_path)
@app.route("/do_something")
def do_something():
next_page = requests.args.get("next", url_for("hello"))
return redirect(next_page)
# 重定向回上一个页面 (封装上述2种方法)
def redirect_back(default="hello", **kwargs):
for target in requests.args.get("next"), request.referer:
if target:
return rediret(target)
return rediret(url_for(default, **kwargs)
对URL进行安全验证
验证next连接
from urlparse import urlparse, urljoin
from flask import request
def is_safe(target):
ref_url = urlparse(request.host_url)
test_url = urlparse(request.host_url, target)
return test_url.scheme in ("http", "heeps") and\
ref_url.netloc == test.netloc
# 优化redirect_back函数
def redirect_back(default="hello", **kwargs):
for target in requests.args.get("next"), request.referer:
if not target:
continue
if is_safe(target):
return rediret(target)
return rediret(url_for(default, **kwargs)
2.5 使用AJAX技术发送异步请求
ajax() 函数支持的参数
url
type
data
dataType
contentType
complete
sucess
error