Flask Web开发实战(狼书)| 笔记第1、2章

前言

2023-8-11

以前对网站开发萌生了想法,又有些急于求成,在B站照着视频敲了一个基于flask的博客系统。但对于程序的代码难免有些囫囵吞枣,存在许多模糊或不太理解的地方,只会照葫芦画瓢。

而当自己想开发一个什么网站的时,就如同摸着石头过河,常在许多小问题上卡住,不知怎么实现,也不知道需要去学习什么才能实现。例如,要做一个聊天室程序,我却不知道在一方发出消息时,如何在另一方实时地显示出来,思虑许久而终归于放弃。

学习系统且详细的知识有其好处,它可以冲退我那种徒手在黑暗中摸索的感觉。读了“狼书”的两个章节,自觉很有收获,此前的许多疑惑也得到了解答。然凡事各有弊益,啃书不是易事,还需下苦功夫。

曾有人对我说,看视频会更有效率。也许他是对的?但我好像更喜欢书籍给我的感觉。但有些讽刺的是,大学至今,我却也没看下来多少书,而时间在我休息的时候,它仍努力奔跑,两载一晃而过。而不少人,也是这相似的困境吧?

回到本文,它是一篇读书笔记,参杂少许个人想法但含量不高,所记零散,主要是作为个人提纲备忘,或许对诸位而言阅读价值不高。若想学习 Flask 框架,我还是很推荐去读“狼书”原著的。


文章目录

    • 前言
    • 开始
      • Git使用
    • 1 初识Flask
      • 1.1 搭建开发环境
      • 1.2 简单示例
    • 2 Flask与HTTP
      • 2.1 重定向回上一个页面
      • 2.2 使用AJAX技术发送异步请求
      • 2.3 HTTP服务器推送
      • 2.4 Web安全防范

开始

5个难度递增的案例:留言板SayHello,个人博客Bluelog,图片社交网站Albumy,待办事项程序Todoism,聊天室CatChat。

前端学习

在这里插入图片描述

Web很多程序离不开javascript,它可以方便、简洁地实现很多页面按逻辑和功能。

了解Git:https://try.github.io/

文本编辑器

在这里插入图片描述

作者的博客:http://greyli.com

Git使用

克隆本书代码仓库:

git clone https://github.com/greyli/helloflask.git

查看当前项目仓库中包含的所有标签:

git tag -n

签出对应标签版本的代码:

git checkout foo

签出前对文件做了修改,需要撤销:

git reset --hard

使用diff命令比较两个标签对应版本之间的变化:

git diff foo bar

使用git客户端直观查看版本变化:

gitk

定期使用git fetch命令来更新本地仓库:

git fetch --all
git fetch --tags
git reset --hard origin/master

在本地复制新的派生仓库,后可以在本地自由修改其中的代码:

git clone https://github.com/你的用户名/helloflask.git

1 初识Flask

Web框架可以让我们不用关心底层的请求响应处理,更方便地编写Web程序。

两个主要依赖:(p3)

  • WSGI(Web Server Gateway Interface,Web服务器网关接口)的工具集——Werkzeug(http://werkzeug.pocoo.org/)
  • Jinja2模板引擎

1.1 搭建开发环境

Pipenv:pip的加强版,让包安装、包依赖管理、虚拟环境管理更加方便。

创建虚拟环境:在项目根目录(即helloflask文件夹中),使用pipenv install命令。Pipfile文件列出的依赖包也会一并被安装。

在这里插入图片描述

显示激活虚拟环境:Pipenv会自动从项目目录下的.env文件中加载环境变量。

# 激活
pipenv shell
# 退出
exit

临时使用虚拟环境中的python解释器:(更推荐)

pipenv run python hello.py

查看当前环境下的依赖情况

pipenv graph

关于Pipfile项目的更多情况,请访问其主页。

使用pipenv install命令安装包时,都是安装到虚拟环境中。相当于使用pip在激活虚拟环境的情况下安装包。

在这里插入图片描述

更新flask版本:(书中为flask-1.0.2)

pipenv update flask

集成开发环境:pycharm专业版提供了更多针对Flask开发的功能,比如创建Flask项目模板,Jinja2语法高亮,与Flask命令行功能集成等。

设置Python解释器(好像已经不需要了):因为PyCharm未集成支持Pipenv。(p10)

1.2 简单示例

from flask import Flask
app = Flask(__name__)@app.route('/')
def index():return '<h1>Hello Flask!</h1>'

Flask类表示一个Flask程序,实例化这个类就得到了我们的程序实例app。__name__对于文件app.py而言,值即为“app”,它帮助Flask在相应的文件夹里找到需要的资源,比如模板和静态文件。(p12)

注册路由:路由负责管理URL和函数之间的映射。

  • 一个视图函数可以绑定多个路由。
  • 动态路由:可以传递参数,并可设置默认参数。

在这里插入图片描述

:Flask内置一个开发服务器,但在实际生产环境中需要使用性能更好的生产服务器。

启动开发服务器

# 未启动虚拟环境下使用
pipenv run flask run
# 在虚拟环境中
flask run
# 命令未找到
python -m flask run

app.run()方法也可启动开发服务器,已经不推荐使用。

flask寻找程序实例

  • 在当前目录下,名为app.pywsgi.py的文件中寻找名为app的程序实例。
  • 根据环境变量FLASK_APP寻找。
# 在linux
$ export FLASK_APP=hello
# 在windows
> set FLASK_APP=hello

管理环境变量:使用python-dotenv包,从.env.flaskenv文件加载。其中.env文件存放一些敏感数据。

pipenv install python-dotenv

可在.flaskenv写入:

# 默认为production(生产环境),开发模式将打开调试器和重载器。
FLASK_ENV=development

使用Pycharm的运行配置(而不使用命令行):在Run --> Edit Configurations(p19)

使服务器外部可见:让局域网用户可以通过你的内网IP进行访问。想要公网访问,可以考虑内网穿透工具、端口转发工具等,如 ngrok、Localtunnel。

flask run --host=0.0.0.0

flask的环境变量:可通过FLASK_<COMMAND>_<OPTION>设置各种选项。

重载器:安装 Watchdog。Werkzeug内置有stat重载器,但耗电严重且准确性一般。

# dev: 开发依赖的包
pipenv install watchdog --dev

打开PythonShell:使用flask打开的shell自动包含程序上下文,并且已经导入了app实例。

flask shell

Flask扩展:使用Flask提供的接口编写的Python库。扩展可以加速开发,但也会降低灵活性,并可能存在bug。

Flask项目配置:可能用到Flask提供的配置、扩展提供的、程序特定的配置。它们用Flask对象的app.config属性作为统一的接口。

  • Flask配置章节:https://flask.pocoo.org/docs/latest/config/
app.config['ADMIN_NAME'] = 'Peter'
# 一次加载多个值
app.config.update()方法

URL:使用url_for(),方便url规则的修改。

  • 相对url与绝对url(p24)

自定义Flask命令

  • Click官方文档(自定义命令):http://click.pocoo.org/6/
@app.cli.command()
def hello():click.echo('Hello, Human!')
> flask hello
Hello, Human!

视图函数之名:可以溯源至MVC架构,即”模型 - 视图 - 控制器”。但flask并不是MVC架构的框架,因为没有内置数据模型的功能(需使用扩展),视图函数成为控制器函数才更加合适。(p28)

2 Flask与HTTP

request对象常用的属性和方法:(p43)

Response类常用属性和方法:(p48)

查看路由列表:这个列表由app.url_map解析得到。其中static为Flask添加的特殊路由,用来访问静态文件。

> flask routes

Flask内置的URL变量转换器:(p37)

URL规则中的转换器<转换器:变量名>

@app.route('goback/<int:year>')
def go_back(year):return '<p>Welcome to %d!</p>' % (2018 - year)

请求钩子:也称回调函数,可以用来注册在请求处理的不同阶段执行的处理函数,如预处理后处理,它们使用装饰器 实现。(p58)

响应:大多数情况下,我们只负责返回响应的主体内容(而不负责首部及各种字段)。Flask会调用make_response()方法将视图函数返回值转换为响应对象。当然,响应也可以包含响应主体、状态码、首部字段 三个部分内容。

可使用redirect(<url字符串>)方法重定向。

@app.route('/')
def hello_flask():return '', 302, {'Location':'https://www.baidu.com'}

:状态码不可儿戏,如将上面的302改为202,则重定向会失效。

错误响应:在视图函数中使用abort(<状态码>),例如:

@app.route('/404')
def not_found():abort(404)

响应格式:在 HTTP 响应中,数据可以通过多种格式传输,默认为 HTML。可以设置不同的 MIME 类型来标识不同的数据格式,MIME 类型在 Content-Type 字段中定义。

# method 1 - 修改响应对象的属性
# @plain 纯文本
from flask import make_response
...
response = make_response("hello")
response.mimetype = 'text/plain'
# method 2 - 设置首部字段
response.headers['Content-Type'] = 'text/html; charset=utf-8'
  • XMLapplication/xml,一般作为 AJAX 请求的响应格式,或是 Web API 的响应格式。

  • JSONapplication/json,指 JavaScript Object Notation(JavaScript对象表示法),更轻量、易解析。

    json模块的dumps()方法,可以将python中的字典、列表、元组数据序列化为json字符串。

# 1 - python标准库的json模块
response = make_response(json.dumps(data))
response.mimetype = 'application/json'
return response
# 2 - 使用flask包装的jsonify()函数
return jsonify(data)

Cookie:HTTP 是无状态协议。Cookie是保存在浏览器上的小型文本数据,保存一定时间,在下一次向同一个服务器发送请求时附带这些数据。但明文存储存在安全隐患。

使用set_cookie()方法设置(参数见p68),从cookies属性获取。

Session:在Flask中,session对象用来存储加密的cookie。

  • 设置程序密钥:通过Flask.secret_key属性;或环境变量SECRET_KEY(可保存在.env文件),在脚本中通过getenv()方法获取。
import os
app.secret_key = os.getenv('SECRET_KEY', 'secret string')

疑问:写进了环境变量还需再脚本中手动获取?那我随便用个环境变量名称是不是也可以?

疑问:看不懂:使用session对象存储的Cookie,用户可以看到其加密后的值,但无法修改它。因为session中的内容使用密钥进行签名,一旦数据被修改,签名的值也会变化。这样再读取时,就会验证失败,对应的session值也会失效。 (p51)

  • session cookie的保存时间

在这里插入图片描述

上下文:Flask中有两种上下文:程序上下文请求上下文

两种上下文在视图函数中都会自动激活,这也意味折一些依赖于上下文的函数只能在视图函数中使用,如url_for()jsonify()等。

也可手动激活程序上下文:

>>> from app import app
>>> from flask import current_app# 方法1
>>> with app.app_context():... current_app.name# 方法2
>>> app_ctx = app.app_context()
>>> app_ctx.push()
>>> current_app.name
>>> app_ctx.pop()# 激活请求上下文类似
>>> from app import app
>>> from flask import request
>>> with app.test_request_context('/hello'):...

在这里插入图片描述

疑惑:g、request等对象如何区分不同的客户端?

上下文钩子:使用它注册的回调函数会在程序上下文被销毁时调用。

@app.teardown_appcontext
def teardown_db(exception):...db.close()

2.1 重定向回上一个页面

利用referrerURL的查询参数。(p59)

referrer:即访问来源。当用户在某个站点单击链接,浏览器向新链接所在的服务器发起请求,请求的数据中包含的HTTP_REFERER字段记录了用户所在的原站点URL。

疑惑:书中判断url是否安全的代码(如下)使我困惑了许久:既然test_url中也与request.host_url做了拼接,那最后的netloc不是必然相同吗?

后来我查找了urljoin(base, url)函数的处理机制:

  • 如果url是一个相对URL,那么urljoin会从url中获取路径部分,并于base中获取的部分合并;
  • 如果url是一个绝对URL,则urljoin会直接返回url

那么在什么情况下,is_safe_url函数的返回值才为False呢?

  • 首先,target是一个绝对URL。
  • 同时,该绝对URL的协议或主机不是本机。

综上,还是感觉该函数的逻辑写得有些隐晦了,不便于理解(肯定不能是我太笨)。

def is_safe_url(target):ref_url = urlparse(request.host_url)test_url = urlparse(urljoin(request.host_url, target))return test_url.scheme in ('http', 'https') and \ref_url.netloc == test_url.netloc

2.2 使用AJAX技术发送异步请求

jQuery中和AJAX相关的方法和具体用法:http://api.jquery.com/category/ajax/

前言

在传统的Web应用中,程序的操作都是基于请求响应循环来实现的。每当页面状态需要变动,或是需要更新数据时,都伴随折一个发向服务器的请求。当服务器响应时,整个页面会重载,并渲染新页面

频繁更新页面会牺牲性能,且影响用户体验。

AJAX是指异步Javascript和XML(Asynchronous JavaScript And XML),是一系列技术的组合体,如XMLHttpRequest、JavaScript、DOM。它让Web程序更像是程序,而非一堆用链接和按钮链接起来的网页资源

可以使用 jQuery 实现AJAX操作:函数ajax()可以发送AJAX请求。

在这里插入图片描述

2.3 HTTP服务器推送

推送技术对比:https://stackoverflow.com/a/12855533/5511489

  • 传统轮询
  • 长轮询
  • SSE(Server-Sent Events)
  • Websocket

2.4 Web安全防范

OWASP(Open Web Application Security Project,开放式Web程序安全项目):https://www.owasp.org 。(p66)

常见攻击方式

  • 注入攻击
  • XSS攻击(Cross-Site Scripting,跨站脚本):将代码注入被攻击者的网站
  • CSRF攻击:(Cross Site Request Forgery,跨站请求伪造):伪造用户的登陆状态。

提示:虽然在实际开发中,通过在”删除“按钮中加入链接来删除资源非常方便,但安全问题应该作为编写代码时的第一考量,应该将这些按钮内嵌在使用了POST方法的form元素中。攻击者就无法通过GET请求来修改用户的数据。

疑惑:未理解csrf攻击的防御原理。


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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringCloud微服务之间如何进行用户信息传递(涉及:Gateway、OpenFeign组件)

目录 1、想达到的效果2、用户信息在微服务之间传递的两种途径3、用RuoYi-Cloud为例进行演示说明&#xff08;1&#xff09;网关将用户信息写在请求头中&#xff08;2&#xff09;业务微服务之间通过OpenFeign进行调用&#xff0c;并且将用户信息写在OpenFeign准备的请求头中&am…

Qt+C++自定义控件仪表盘动画仿真

程序示例精选 QtC自定义控件仪表盘动画仿真 如需安装运行环境或远程调试&#xff0c;见文章底部个人QQ名片&#xff0c;由专业技术人员远程协助&#xff01; 前言 这篇博客针对<<QtC自定义控件仪表盘动画仿真>>编写代码&#xff0c;代码整洁&#xff0c;规则&…

浅谈SMT行业MES系统生产管理的特点

一、SMT生产车间在电子制造中起重要作用的部分&#xff0c;主要具备以下生产特点&#xff1a; 1.高密度和高速度&#xff1a; SMT生产车间中的电子元器件一般来说较为精小&#xff0c;且被紧密地排列在PCB上。这就要求SMT生产车间的机械设备具备高精度和高速度&#xff0c;确保…

怎么对视频进行压缩?

怎么对视频进行压缩&#xff1f;视频压缩&#xff0c;我们都知道是将视频文件进行压缩变小的过程&#xff0c;是我们日常办公中较为常用的手段。现如今&#xff0c;在视频技术不断发展与创新的基础上&#xff0c;视频分辨率也在不断提高&#xff0c;进而导致文件占有量也非常大…

前后端分离------后端创建笔记(05)用户列表查询接口(下)

本文章转载于【SpringBootVue】全网最简单但实用的前后端分离项目实战笔记 - 前端_大菜007的博客-CSDN博客 仅用于学习和讨论&#xff0c;如有侵权请联系 源码&#xff1a;https://gitee.com/green_vegetables/x-admin-project.git 素材&#xff1a;https://pan.baidu.com/s/…

设计HTML5图像和多媒体

在网页中的文本信息直观、明了&#xff0c;而多媒体信息更富内涵和视觉冲击力。恰当使用不同类型的多媒体可以展示个性&#xff0c;突出重点&#xff0c;吸引用户。在HTML5之前&#xff0c;需要借助插件为网页添加多媒体&#xff0c;如Adobe Flash Player、苹果的QuickTime等。…

DoIP学习笔记系列:(六)满足AES128-CMAC算法的“安全认证”.dll生成实践

文章目录 1. 算法Demo2. 算法实现传送门 DoIP学习笔记系列:导航篇 AES128-CMAC算法在汽车电子控制单元的软件开发中涉及到安全相关的需求经经常用到,具体的算法原理请各位小伙伴自行百度,本篇主要向大家分享该算法如何集成到.dll文件中,在OTA、刷写等场景作为$27服务的安全…

python -m参数的作用(python3 -m)

文章目录 Python -m 参数的作用直接执行模块代码模块自测试环境隔离避免名称冲突 其他&#xff1a;python3 --help Python -m 参数的作用 在Python中&#xff0c;使用-m参数可以执行一个模块作为脚本。它是用于从命令行直接运行一个Python模块的标志。这种方式具有以下几个方面…

RocketMQ消息轨迹产生的背景以及使用方式

这里是weihubeats,觉得文章不错可以关注公众号小奏技术&#xff0c;文章首发。拒绝营销号&#xff0c;拒绝标题党 背景 最近在维护RocketMQ经常会出现这种问题 消息发送方和接收方出现扯皮&#xff0c;消息发送方说我的消息已经发送成功了&#xff0c;消费方说我没接收到消息。…

uni——初次加载问题处理(赋值后再调用)

案例描述 此案例中 一进页面接收good_id并调用接口&#xff0c;这个流程正常。 这个changeNum也是一进页面就触发了&#xff08;组件购物车加减自带&#xff09;&#xff0c;且触发的顺序在onload赋值id之前&#xff0c;这时候good_id还是为空&#xff0c;所以接口报错。如何处…

十一、避开客户端控件——收集用户数据

文章目录 一、HTML表单1.1 长度限制1.2 基于脚本的确认1.3 禁用的元素 二、浏览器拓展2.1 常见的浏览器拓展技术2.2 攻击浏览器扩展的方法 一、HTML表单 应用程序使用客户端控件限制客户端提交的数据的另一个主要控制对象&#xff0c;是由客户端计算机自己收集的数据。 HTML表单…

Python-OpenCV中的图像处理-图像直方图

Python-OpenCV中的图像处理-图像直方图 图像直方图统计直方图绘制直方图Matplotlib绘制灰度直方图Matplotlib绘制RGB直方图 使用掩膜统计直方图直方图均衡化Numpy图像直方图均衡化OpenCV中的直方图均衡化CLAHE 有限对比适应性直方图均衡化 2D直方图OpenCV中的2D直方图Numpy中2D…

Medical Isolated Power Supply System in Angola

安科瑞 华楠 Abstract: Diagnosis and treatment in modern hospitals are inseparable from advanced medical equipment, which are inseparable from safe and reliable power supply. Many operations often last for several hours, and the consequences of a sudden pow…

欢迎光临,博客网站

欢迎光临&#xff1a;YUNYE博客~https://yunyeblog.com/更多的文章&#xff0c;供大家参考学习&#xff01;&#xff01;&#xff01;

Mybatis 源码 ④ :TypeHandler

文章目录 一、前言二、DefaultParameterHandler1. DefaultParameterHandler#setParameters1.1 UnknownTypeHandler1.2 自定义 TypeHandler 三、DefaultResultSetHandler1. hasNestedResultMaps2. handleRowValuesForNestedResultMap2.1 resolveDiscriminatedResultMap2.2 creat…

VSCode使用SSH无密码连接Ubuntu

VSCode使用SSH无密码连接Ubuntu 前提条件&#xff1a; 1. 能够正常使用vscode的Remote-ssh连接Ubuntu 2. Ubuntu配置静态ip&#xff08;否则经常需要修改Remote-ssh的配置文件里的IP&#xff09; 链接-> ubuntun 18.04设为静态ip&#xff08;.net模式&#xff0c;可连接…

初学HTML:在线简易画板设计。

最近在HTML&#xff0c;记录下一点点成果。 设计了一个简易画板&#xff0c;通过HTML的Canvas元素实现一个在线画板&#xff0c;用户可以在上面绘制图形或涂鸦。 下面是运行效果&#xff1a; 下面是代码&#xff1a; <!DOCTYPE html> <html> <head><ti…

蓝绿灰度发布的介绍

背景介绍 蓝绿灰度发布 介绍 蓝绿部署中&#xff0c;一共有两套系统&#xff1a;一套是正在提供服务系统(也就是上面说的旧版)&#xff0c;标记为绿色&#xff1b;另一套是准备发布的系统&#xff0c;标记为蓝色。两套系统都是功能完善的&#xff0c;并且正在运行的系统&…

安全 1自测

常见对称加密算法&#xff1a; DES&#xff08;Data Encryption Standard&#xff09;&#xff1a;数据加密标准&#xff0c;速度较快&#xff0c;适用于加密大量数据的场合&#xff1b; 3DES&#xff08;Triple DES&#xff09;&#xff1a;是基于DES&#xff0c;对一块数据用…

C语言刷题训练【第11天】

大家好&#xff0c;我是纪宁。 今天是C语言笔试刷题训练的第11天&#xff0c;加油&#xff01; 文章目录 1、声明以下变量&#xff0c;则表达式: ch/i (f*d – i) 的结果类型为&#xff08; &#xff09;2、关于代码的说法正确的是&#xff08; &#xff09;3、已知有如下各变…