flask框架的请求处理逻辑

在这里插入图片描述

Django 和 Flask 是 Python 的两个非常流行的 Web 框架,它们对 HTTP 请求的处理方式有一些区别。

在 Django 中,当你的应用接收到一个 HTTP 请求时,Django 会将请求封装为一个 HttpRequest 对象,然后通过视图函数的参数传递这个对象。这个 HttpRequest 对象包含了关于这个 HTTP 请求的所有信息,比如 GET/POST 参数,HTTP headers,用户信息等。所以在 Django 中,你处理一个 HTTP 请求的方式就是读取并操作这个 HttpRequest 对象。

示例:

def my_view(request):
    user = request.user
    method = request.method
    ...

在 Flask 中,处理方式有些不同。Flask 使用了一种称为 “线程局部变量” 的技术来保存请求对象和其他对象。这意味着在一个线程中,你可以直接访问 request 对象,而不需要将其作为参数传递到你的视图函数。这是因为 Flask 为每个线程创建了自己的请求上下文,你可以在上下文中直接访问 request 对象。

示例:

from flask import request

@app.route('/')
def my_view():
    user_agent = request.headers.get('User-Agent')
    ...

尽管 Flask 的方式在某些情况下可能看起来更加简洁,但是它也有一个缺点,那就是这种方法在处理并发请求时可能会引起混淆,尤其是当你试图在不同的线程之间共享数据时。而 Django 的方式更加显式,因此更加清晰,但需要更多的代码量。

总的来说,这两种方法都有各自的优点和缺点,具体哪一种更好取决于你的具体需求和喜好。

线程局部变量

"线程局部变量"也称为线程局部存储(Thread Local Storage, TLS),是指每个线程有其自己的独立变量,而不是在线程之间共享。这是一个编程的概念,在多线程编程中非常有用,因为你可以将某些数据(如 Flask 的 request 对象)绑定到当前线程,而其他线程则不能访问到。这样可以避免数据的混淆和冲突。

Flask 使用线程局部存储的方式来处理 HTTP 请求。在 Flask 中,HTTP 请求被封装在 request 对象中,然后保存在一个特殊的上下文环境中,这个上下文环境是绑定到当前线程的。

Flask 的上下文环境分为两种:应用上下文和请求上下文。请求上下文是用于管理 HTTP 请求的信息的,包括请求的 headers,body,cookies 等。当 Flask 开始处理一个 HTTP 请求时,它会创建一个新的请求上下文,然后将 request 对象保存在其中。

由于请求上下文是绑定到当前线程的,因此你可以在同一个线程的任何地方访问 request 对象,无论是视图函数,还是其他函数。你只需要从 flask 模块导入 request 对象即可。

以下是一个简单的示例:

from flask import Flask, request

app = Flask(__name__)

@app.route('/')
def hello():
    user_agent = request.headers.get('User-Agent')
    return 'Hello, Your user agent is {}'.format(user_agent)

在这个示例中,我们在 hello 视图函数中访问了 request 对象。虽然 request 对象没有作为参数传递给 hello 函数,但我们仍然可以在函数内部访问它,这是因为 request 对象被保存在了线程局部的请求上下文中

然而,由于每个请求有自己的请求上下文,所以当你尝试在一个请求之外(例如在两个请求之间,或者在请求之后)访问 request 对象时,Flask 将会抛出一个错误,因为此时没有活跃的请求上下文

所以说,Flask 使用线程局部存储和上下文环境的方式来处理 HTTP 请求,这种方式既方便又高效,但同时也需要开发者理解上下文和线程局部存储的概念。

在 Flask 中,request 对象是在每次 HTTP 请求到来时由 Flask 自动创建和赋值的。这个过程是在 Flask 的内部机制中完成的,当 Flask 收到一个 HTTP 请求时,它首先解析 HTTP 请求,提取出所有相关信息(如请求头、请求方法、请求体等),然后根据这些信息创建一个 request 对象。

在创建 request 对象后,Flask 会将其保存在一个特殊的线程局部的请求上下文中。这样,开发者就可以在视图函数或其他地方通过 flask.request 来访问到当前 HTTP 请求的 request 对象。

当请求处理完毕,响应被发送回客户端后,Flask 会清理请求上下文,request 对象就不再可用了。

这就是 Flask 在何时以及如何赋值 request 对象的大概过程。这是 Flask 为了方便开发者处理 HTTP 请求而封装的一种机制,使得开发者可以在任何需要的地方通过 flask.request 来访问当前 HTTP 请求的所有信息。

补充:

在 Flask 中,每个 HTTP 请求都有其自己的 request 对象,并且这个对象被保存在特定于该请求的请求上下文中。也就是说,每个请求的 request 对象都是独立的,即使这两个请求指向的是同一个路由。

这是由 Flask 的设计决定的。每次当 Flask 开始处理一个新的 HTTP 请求时,它会创建一个新的请求上下文,并将新创建的 request 对象保存在其中。在请求处理完毕,响应被发送回客户端后,Flask 会清理请求上下文,包括其中的 request 对象。

所以,尽管两个路由可能处理相同类型的 HTTP 请求,但是它们处理的 request 对象并不是同一个。每个请求的 request 对象都包含了关于该请求的所有信息,如请求头,请求参数等。

以下是一个简单的例子来说明这个概念:

from flask import Flask, request

app = Flask(__name__)

@app.route('/route1')
def view1():
    return 'You are at route1 and your user agent is: {}'.format(request.headers.get('User-Agent'))

@app.route('/route2')
def view2():
    return 'You are at route2 and your user agent is: {}'.format(request.headers.get('User-Agent'))

在这个例子中,view1 和 view2 是两个不同的路由,它们分别处理两个不同的 HTTP 请求。虽然它们都访问 request 对象来获取用户的 User-Agent,但这个 request 对象并不是同一个,每个请求有自己独立的 request 对象。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/45224.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Kubernetes_核心组件_kubelet_kubelet服务全解析(二)

文章目录 前言kubelet 架构kubelet 职责Node管理(节点管理)Pod管理 kubelet管理Podkubelet如何管理当前节点上所有Podkubelet三个端口kubelet获取Pod清单kubelet通过CRI接口管理Pod以及里面的容器 PodWorker的工作细节PodWorker的工作细节PLEG组件PLEG报错 kubelet创建并启动Po…

kafka权威指南学习以及kafka生产配置

0、kafka常用命令 Kafka是一个分布式流处理平台,它具有高度可扩展性和容错性。以下是Kafka最新版本中常用的一些命令: 创建一个主题(topic): bin/kafka-topics.sh --create --topic my-topic --partitions 3 --replic…

【高危】Foxit 福昕PDF阅读器 Field Calculate 释放后使用漏洞(PoC)

漏洞描述 Foxit PDF阅读器是福昕软件公司推出的一款广泛使用的PDF文档阅读器。 在受影响版本中,由于其javascript引擎存在use-after-free漏洞,攻击者可以构造恶意的PDF文件,通过文件中包含的deletePages()等操作使福昕PDF阅读器过早删除与页…

若依分离版——解决配置双数据源oracle,mysql分页错误问题

1. 按照若依的手册配置双数据源mysql,oracle 2. 在service指定 数据源 DataSource(value DataSourceType.MASTER) 或者DataSource(value DataSourceType.SLAVE) Service public class SysPostServiceImpl implements ISysPostService {/*** 查询岗位信息集合* …

9.python设计模式【外观模式】

内容:为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一个子系统更加容易使用。 角色: 外观(facade)子类系统(subsystem classes) UML图 举…

react实现页面动态表单设计器(自定义推拽表单)

react实现页面动态表单设计器(自定义推拽表单) 实现效果安装插件使用组件介绍基本设置,可设置控件标签,是否必填,校验规则校验规则有如下几种多选,下拉,单选可动态设置每个选择的label以及值 实…

实例025 带分隔栏的窗体

实例说明 在软件开发中,经常需要将界面分成几个部分,而且这几个部分又可以自由调整大小。运行本例,实例效果如图1.25所示。 技术要点 在.NET 2.0框架中可以非常轻松的实现这一功能,只要在窗体中加入SplitContainer控件即可。Sp…

(链表) 剑指 Offer 24. 反转链表 ——【Leetcode每日一题】

❓剑指 Offer 24. 反转链表 难度&#xff1a;简单 定义一个函数&#xff0c;输入一个链表的头节点&#xff0c;反转该链表并输出反转后链表的头节点。 示例: 输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL 限制&#xff1a; 0 < …

Spring Boot中整合MyBatis(基于xml方式基于注解实现方式)

一、前提准备 在Spring Boot中整合MyBatis时&#xff0c;你需要导入JDBC&#xff08;不需要手动添加&#xff09;和Druid的相关依赖。 JDBC依赖&#xff1a;在Spring Boot中整合MyBatis时&#xff0c;并不需要显式地添加JDBC的包依赖。这是因为&#xff0c;当你添加mybatis-sp…

LLM Data Pipelines: 解析大语言模型训练数据集处理的复杂流程

编者按&#xff1a;在训练大语言模型的过程中,构建高质量的训练数据集是非常关键的一步&#xff0c;但关于构建大模型训练所需数据集的通用数据处理流程&#xff08;Data pipelines)的相关资料极为稀少。 本文主要介绍了基于Common Crawl数据集的数据处理流程。首先,文章概述了…

2022年圣诞节 | 用代码实现简单圣诞树

2022年圣诞节到来啦&#xff0c;很高兴这次我们又能一起度过~ 一、前言 本文我们用 Python 来画一棵带背景音乐效果的雪夜圣诞树以及使用 HTMLCSSJS 在页面渲染出动态圣诞树&#xff0c;所涉及到的源码均来自GitHub开源站点。 二、效果展示 Python HTMLCSSJS 三、编码实现 …

OpenTDF数据加密引擎

OpenTDF是Virtru公司的开源项目。 Virtru基于OpenTDF开发了用于google Workspace和Microsoft 365的相关数据安全产品。 简介 virtru公司基于opentdf开发挺多产品的,都是数据安全类产品。 能把opentdf开源,已经非常不容易了。 opentdf的代码看起来还是比较整齐和成熟的。…

aPaaS开发 VS 传统软件开发?

aPaaS开发 VS 传统软件开发&#xff1f;aPaaS的优势和平台选型&#xff1a; &#xff08;1&#xff09;aPaaS模式具备成本优势、开发速度快、多场景适用等特点&#xff0c;在资本市场备受关注&#xff1b; &#xff08;2&#xff09;aPaaS能够覆盖企业销售、项目管理、业务财…

微服务远程调用openFeign简单回顾

目录 一. OpenFeign简介 二. OpenFeign原理 演示使用 provider模块 消费者模块 配置全局feign日志 示例源代码: 一. OpenFeign简介 OpenFeign是SpringCloud服务调用中间件&#xff0c;可以帮助代理服务API接口。并且可以解析SpringMVC的RequestMapping注解下的接口&#x…

学习day52

1.关于 error Component name "School" should always be multi-word vue/multi-word-component-names 这里是因为脚手架的规范原因&#xff0c; 解决办法&#xff1a; 我是在vue.comfig.js文件中加入了一条配置&#xff0c;即 lintOnSave:false 整个文件的完整…

Java 实现提取富文本中包含特定字符串的图片 src 属性值

&#x1f468;&#x1f3fb;‍&#x1f4bb; 热爱摄影的程序员 &#x1f468;&#x1f3fb;‍&#x1f3a8; 喜欢编码的设计师 &#x1f9d5;&#x1f3fb; 擅长设计的剪辑师 &#x1f9d1;&#x1f3fb;‍&#x1f3eb; 一位高冷无情的编码爱好者 大家好&#xff0c;我是 DevO…

Nginx配置server_name讲解

文章目录 1.Nginx配置中没有server_name会怎样&#xff1f;2.Nginx配置server_name的匹配规则3.正则表达式规则 1.Nginx配置中没有server_name会怎样&#xff1f; 此时Nginx会自动设置成 server_name ""; 它不会匹配任何域名&#xff0c;导致Nginx会优先将HTTP请求交…

Cesium态势标绘专题-弓形(标绘+编辑)

标绘专题介绍:态势标绘专题介绍_总要学点什么的博客-CSDN博客 入口文件:Cesium态势标绘专题-入口_总要学点什么的博客-CSDN博客 辅助文件:Cesium态势标绘专题-辅助文件_总要学点什么的博客-CSDN博客 本专题没有废话,只有代码,代码中涉及到的引入文件方法,从上面三个链…

3分钟,快速上手Postman接口测试

Postman是一个用于调试HTTP请求的工具&#xff0c;它提供了友好的界面帮助分析、构造HTTP请求&#xff0c;并分析响应数据。实际工作中&#xff0c;开发和测试基本上都有使用Postman来进行接口调试工作。有一些其他流程的工具&#xff0c;也是模仿的Postman的风格进行接口测试工…

Unity 性能优化一:性能标准、常用工具

性能标准 推荐耗时&#xff1a; 性能提现到玩家直观感受&#xff0c;就是帧率&#xff0c;为了达到要求的帧率&#xff0c;就要控制CPU的耗时&#xff0c;不同类型的游戏&#xff0c;对帧率要求不一样。下面是推荐耗时&#xff1a; 推荐内存&#xff1a; 避免游戏闪退的重点…