目录

Python-Flask-使用不同的-HTTP-方法类型处理请求

Python Flask 使用不同的 HTTP 方法类型处理请求

Python Flask 使用不同的 HTTP 方法类型处理请求

HTTP 是基于客户端和服务端的请求-回应模型的。客户端(例如,网页服务器)可以发送不同的动词,或更合适的,调用方法来区别对服务器请求的类型。这些方法包括 GETPOSTPUTDELETEHEADPATCH ,以及 OPTIONSGETPOST 是最常用的 HTTP 方法。接下来,我们仅仅使用这两个方法来讲解网页开发概念。

在讨论这两个方法之前,理解 HTTP 的两个组件是非常重要的,也就是 HTTP 请求和 HTTP 回应。一个 HTTP 请求会被分成三部分:

  • 请求行(Request Line):这一行包含了使用的方法,请求的 URI ,和使用的 HTTP 协义的版本。

    GET /home HTTP/1.1
  • 请求头字段(Header fields):请求头是元数据,提供适用于请求的信息。每个头部都以关键字-值对的方式提供,用冒号(:)分隔;

  • 请求体(可选):它是一个占位符,我们可以添加额外的数据。对于一个网页应用程序来说,我们可以随 POST 请求一起在请求体内部发送表单数据。对于一个 REST 应用接口,我们可以在请求体内给 PUTPOST 请求发送数据。

当我们发送一个 HTTP 请求时,我们会得到一个 HTTP 回应,作为请求的结果。HTTP 回应和 HTTP 请求有相似的部分:

  • 状态行:这行指明了回应是成功的,还是失败的。错误代码会出现在状态行上:

    HTTP/1.1 200 OK

    200 这个状态码,或在闭区间 [200,299] 之间的状态码,代表成功。错误码在闭区间 [400,499] 内,表示客户端错误,错误码在闭区间 [500,599] 之间表示服务端错误;

  • 回应头:回应头字段和 HTTP 请求头字段类似;

  • 回应体(可选):虽然是可选的,但它是 HTTP 回应的关键部分。回应体里可以包含网页应用程序的 HTML 页面或其它任何格式的数据。

GET 方法用来发送请求以获取特定资源,特定资源是在 URL 中标识出来的,并且可以选择将查询字符串添加为 URL 的一部分。 ? 在 URL 中被用来分隔查询字符串和基础 URL。例如,如果我们用搜索工具 xx.com 搜 Python ,我们会在浏览器地址栏里看到下的 URL:

https://www.xx.com/search?q=Python

在上面的 URL 中, q=Python 是一个查询字符串。查询字符串用来携带 key=value 数据。这种访问资源的方案是流行的,因为它的简单。但是它是有缺陷的。在 URL 中,查询字符串的数据是可见的,这意味着我们不能在查询字符串中发送敏感信息,比如用户名和密码。查询字符串的长度不能超过 255 字符。然而,因为简单,搜索公司使用 GET 方法搜索网站。在 POST 方法中,数据通过 HTTP 请求体发送,这就消除了 GET 方法的限制。数据不会作为 URL 的一部分出现,发送到服务器的数据也没有数量的限制。同样, POST 方法对数据的类型也没有限制。

Flask 提供了好几个方便的方法用来区别一个请求是用 GETPOST 或任务其它方法发送的。在我们下面的例子中,我们演示了两个方案。第一个方案使用 route 装饰器,它带有一个精确的期望方法列表;第二个方案使用一个特定方法类型装饰器,比如 get 装饰器或 post 装饰器。下面是完整的代码:

# 使用方法类型映射请求

from flask import Flask, request
app = Flask(__name__)

@app.route("/submit", methods=["GET"])
def req_with_get():
    return "接收到了一个 GET 请求。"

@app.post('/submit')
def req_with_post():
    return "接收到了一个 POST 请求。"

@app.route("/submit2", methods=["GET", "POST"])
def both_get_post():
    if request.method == "GET":
        return "接收到了一个 GET 请求 2。"
    else:
        return "接收到了一个 POSt 请求 2。"


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

下面让我们逐一讨论我们的示例代码中的三个路由定义和相应的函数:

  • 在第一个路由定义(@app.route(“/submit”, methods=[“GET”]))中,我们使用 route 装饰器映射 URL ,把 GET 类型的请求映射到一个 Python 函数。使用这个装饰设定,Python 函数将会处理 /submit 这个 URL 的 GET 请求;
  • 在第二个路由定义(@app.post(‘/submit’))中,我们使用 post 装饰器,并且只指定请求 URL。这是把 POST 方法映射到 Python 函数的简单方法。这个新的设置方法和第一个方案是等价的。我们自可以使用 get 装饰器给 GET 定义处理器;
  • 在第三个路由定义(@app.route(“/submit2”, methods=[“GET”, “POST”]))中,我们把单个 URL 的 GETPOST 这两个请求上映射到同样一个方法上。这是一种简单的方案,用这种方案我们可以使用一个处理器处理任何类型的请求。在 Python 函数内部,使用请求对象的 method 属性来标识请求是 GET 还是 POST 。请注意,一旦我们将请求包导入到程序中,web服务器就会将请求对象提供给我们的Flask应用程序。这种方法为客户端提供了灵活性,可以使用相同的URL使用两种方法中的任何一种提交请求,作为开发人员,我们将它们映射到一个Python函数。

我们可以通过 curl 实用程序更方便地测试此代码示例,因为在不定义 HTML 表单的情况下提交 POST 请求并不容易。以下 curl 命令可用于向我们的网页应用程序发送HTTP请求:

curl -X GET http://localhost:5000/submit
curl -X POST http://localhost:5000/submit
curl -X GET http://localhost:5000/submit2
curl -X POST http://localhost:5000/submit2

<完>