2.Flask与HTTP

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,324评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,356评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,328评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,147评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,160评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,115评论 1 296
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,025评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,867评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,307评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,528评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,688评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,409评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,001评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,657评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,811评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,685评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,573评论 2 353