一、请求(request)与响应(response)原理
当我们在浏览器中的地址栏中输入这个URL,然后按下Enter,稍等片刻,浏览器会显示一个问候页面。这背后到底发生了什么?你一定可以猜想到,这背后也有一个类似我们编写的程序运行着。它负责接收用户的请求,并把对应的内容返回给客户端,显示在用户的浏览器上。事实上,每一个Web应用都包含这种处理模式,即“请求-响应循环(Request-Response Cycle)”:客户端发出请求,服务器处理请求并返回响应,如下图所示:
附注 客户端(Client Side)是指用来提供给用户的与服务器通信的各种软件。在本书中,客户端通常指Web浏览器(后面简称浏览器),比如Chrome、Firefox、IE等;服务器端(Server Side)则指为用户提供服务的服务器,也是我们的程序运行的地方。
这是每一个Web程序的基本工作模式,如果再进一步,这个模式又包含着更多的工作单元,
下图展示了一个Flask程序工作的实际流程:
从上图可以看出,HTTP在整个流程中起到了至关重要的作用,它是客户端和服务器端之间沟通的桥梁。
当用户访问一个URL,浏览器便生成对应的HTTP请求,经由互联网发送到对应的Web服务器。Web服务器接收请求,通过WSGI将HTTP格式的请求数据转换成我们的Flask程序能够使用的Python数据。在程序中,Flask根据请求的URL执行对应的视图函数,获取返回值生成响应。响应依次经过WSGI转换生成HTTP响应,再经由Web服务器传递,最终被发出请求的客户端接收。浏览器渲染响应中包含的HTML和CSS代码,并执行JavaScript代码,最终把解析后的页面呈现在用户浏览器的窗口中。
Request对象(from flask import Flask,request)
这个请求对象封装了从客户端发来的请求报文,我们能从它获取请求报文中的所有数据。
我们先从URL说起。假设请求的URL是http://helloflask.com/hello?name=Grey,当Flask接收到请求后,请求对象会提供多个属性来获取URL的各个部分,常用的属性如下表所示:
除了URL,请求报文中的其他信息都可以通过request对象提供的属性和方法获取,其中常用的部分如下表所示:
在我们的示例程序中实现了同样的功能。当你访问http://localhost:5000/hello?name=Grey,页面加载后会显示“Hello, Grey!”。这说明处理这个URL的视图函数从查询字符串中获取了查询参数name的值,如下所示:
from flask import Flask, request app = Flask(__name__) @app.route('/hello') def hello():
print(request.method) #打印请求方式
print(request.url) #打印请求地址
name = request.args.get('name', 'Flask') # 获取查询参数name的值 return '<h1>Hello, %s!</h1>' % name # 插入到返回值中
需要注意的是,和普通的字典类型不同,当我们从request对象中类型为MutliDict或ImmutableMultiDict的属性(比如files、form、args)中直接使用键作为索引获取数据时(比如request.args['name']),如果没有对应的键,那么会返回HTTP 400错误响应(Bad Request,表示请求无效),而不是抛出KeyError异常,如下图所示。为了避免这个错误,我们应该使用get()方法获取数据,如果没有对应的值则返回None;get()方法的第二个参数可以设置默认值,比如requset.args.get('name', 'Human')。
二、从路径中获取参数
Flask不同于Django直接在定义路由时编写正则表达式的方式,而是采用转换器;
URL中路径参数的获取:
语法:<>
作用:提取URL路径参数
效果:将该位置数据以字符串格式
匹配,值同样为字符串
类型,转换器中的值为参数名传入视图
@app.route('/index/<id>',methods=["GET","POST"]) #def first_flask(id): #视图函数 print(id)
return"hello user %S!" % id
三、设定视图函数能够处理的请求方式
HTTP有很多URL方法的。默认路由只回应GET请求,但是我们可以在装饰器app.route中传递methods参数改变请求方式,
当我们需要视图函数能够处理多种请求时,需要在对应的视图函数的装饰器上进行修改增加一行代码:methods=["get","post"]如果还有其他的请求方式需要添加,在括号中继续加入对应的请求方式即可。
@app.route('/index/<id>',methods=["GET","POST"])
四、返回指定的前端网页(利用render_template()渲染html)
render_template()有什么用?
在Python代码中 直接生成 HTML 缺点很多,比如笨拙,效率低,可读性差。因此, Flask 提供了 Jinja2 模板引擎来帮助开发者高效灵活生成HTML。
使用该方法可以渲染模板,你只要提供模板名称和需要作为参数传递给模板的变量就行了.
html模板文件的位置
模板即自己写好的模板html文件,需要放在templates
文件夹内。目录结构如下:
/application.py /templates #创建一个新的空文件夹且命名templates. /hello.html
实例
from flask import Flask, render_template app = Flask(__name__) @app.route('/') def index(): return render_template('files_list.html') if __name__="__main__" : app.run(debug=True)
五、返回JSON数据(import json,from flaskimport Flask,jsonify)
在前后端分离的时代,后端一般返回前端的数据就是json格式的响应数据。
而json格式的响应数据其实实际上就是一个字符串。
要知道Flask如何返回json响应数据,首先就需要知道如何将字典dict转化为json字符串。
In [1]: import json In [2]: data = {"user_name":"libai", "user_pwd": "123456"} In [3]: type(data) Out[3]: dict # 将dict转为json字符串 In [4]: res = json.dumps(data) In [5]: res Out[5]: '{"user_name": "libai", "user_pwd": "123456"}' In [6]: type(res) Out[6]: str # 将json字符串转为dict In [7]: rec = json.loads(res) In [9]: rec Out[9]: {'user_name': 'libai', 'user_pwd': '123456'} In [10]: type(rec) Out[10]: dict
视图函数使用json库返回json响应数据
from flask import Flask, request import json # 实例化app app = Flask(import_name=__name__) @app.route('/login', methods=["GET","POST"]) def login(): data = { "user_name": "libai", "user_age": 18, } res_json = json.dumps(data) return res_json if __name__ == '__main__': app.run(debug=True)
在浏览器请求如下:
如果单纯直接返回响应消息,Content-Type:text/html
是不正确的,应该改为application/json
才对。
修改响应消息的headers如下:
from flask import Flask, request, abort, make_response import json # 实例化app app = Flask(import_name=__name__) @app.route('/login', methods=["GET","POST"]) def login(): data = { "user_name": "libai", "user_age": 18, } res_json = json.dumps(data) # return 响应体, 状态码, 响应头 return res_json, 200, {"Content-Type":"application/json"} if __name__ == '__main__': app.run(debug=True)
在浏览器的请求响应如下:
可以看到正常返回json数据了。
但是可以感觉到这样其实挺麻烦的。在Flask框架中有一个jsonify
的方法可以将这个过程简化。
使用jsonify来返回json响应数据
from flask import Flask, jsonify # 实例化app app = Flask(import_name=__name__) @app.route('/login', methods=["GET","POST"]) def login(): data = { "user_name": "libai", "user_age": 18, } return jsonify(data) if __name__ == '__main__': app.run(debug=True)
浏览器请求如下:
可以看到,使用jsonify
返回json响应数据是最简单的一种方式。
- 另外
jsonify
不单单可以将dict转为json响应数据,还可以直接往里面写参数值
jsonify(token=123456, gender=0)
示例如下:
from flask import Flask, jsonify # 实例化app app = Flask(import_name=__name__) @app.route('/login', methods=["GET","POST"]) def login(): return jsonify(token=123456, gender=0) if __name__ == '__main__': app.run(debug=True)
浏览器请求如下:
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。