Flask-1-04-Request

在开始学习代码以前先介绍一个工具叫作Postman :

对就长上面那样,它是一款很是适合开发人员使用的调试工具,能够根据你发起的请求携带一些参数,起码我如今是这么理解的,各类你要发送给服务端的参数

那么就进入今天的正题:

获取请求从参数:

首先咱们须要从框架中导入,Flask为咱们准备的request,它就是Flask中表示当前请求的request对象。request对象中保存了一次Http请求的信息

首先咱们经过Postman为咱们发起一条请求信息,在这以前,咱们须要先定义一个视图,让它找到请求的路径

# coding:utf-8
from flask import Flask, request

app = Flask(__name__)

@app.route('/index', methods=['GET', 'POST'])
def index():
    return 'test ok'

if __name__ == '__main__':
    app.run(host='0.0.0.0', debug=True)

不重要的注意:为了让文档看起来不那么冗长,我选择性的减小了空行html

经过上面一系列的操做大体应该了解若是发送一次请求,接下来的有些操做,有多是文字形容不太清楚的。因此仔细的看一下截图的每个带有选框和你下载Postman不同的地方。前端

Request的经常使用属性

  • form

    一个包含解析过的从 POST 或 PUT 请求发送的表单对象的 MultiDict 。请注意上传的文件不会在这里,而是在 files 属性中。python

  • args

    一个包含解析过的查询字符串( URL 中问号后的部分)内容的 MultiDict 。json

  • values

    一个包含 form 和 args 所有内容的 CombinedMultiDict 。flask

  • cookies

    一个包含请求中传送的全部 cookie 内容的 dict 。后端

  • stream

    若是表单提交的数据没有以已知的 mimetype 编码,为性能考虑,数据会不经修改存储在这个流中。大多数状况下,使用能够把数据提供为字符串的 data 是更好的方法。流只返回一次数据。api

  • headers

    进入请求的标头存为一个相似字典的对象。浏览器

  • data

    若是进入的请求数据是 Flask 不能处理的 mimetype ,数据将做为字符串存于此。服务器

  • files

    一个包含 POST 和 PUT 请求中上传的文件的 MultiDict 。每一个文件存储为FileStorage 对象。其基本的行为相似你在 Python 中见到的标准文件对象,差别在于这个对象有一个 save() 方法能够把文件存储到文件系统上。cookie

  • environ

    底层的 WSGI 环境。

  • method

    当前请求的 HTTP 方法 (POST , GET 等等)

 

首先咱们经过Postman发送一个from表单请求,先写好后台接收的视图,而后再发起请求

# coding:utf-8
# request中包含了前端发送过来的全部请求数据
from flask import Flask, request

app = Flask(__name__)

@app.route('/index', methods=['GET', 'POST'])
def index():
    # 接收客户端请求过来的数据
    # 经过requset.form能够直接提取请求体中的表单格式的数据, 是一个相似字典的对象
    name = request.form.get('username')
    pwd = request.form.get('password')
    return 'username = %s, password = %s' % (name, pwd)

if __name__ == '__main__':
    app.run(host='0.0.0.0', debug=True)

一个不重要的注意:请把注意点放在Flask框架上,这个Postman不是重点,主要是后端经过request接收前端发送过来的数据才是重点,理清request才是最主要的。你也能够经过页面发送到视图,你任何能够发起请求的方式都是能够的不仅仅只有Postman

经过代码能够看出,咱们经过request.form来接受前端发送过来的表单数据,接受的是相似字典的一个对象,既然是字典咱们也能够经过这种方式来赋值给变量 request.form['username'],可是并不推荐后端来这么作。由于使用get()方法获取,就算找不到最多也就是返回一个None,不会对你的程序形成什么没必要要的错误,可是若是这里你经过request.form['username']这种方式获取得话,在Web程序当中会直接返回一个400的状态码,会给你爆出一个错误,影响你的页面的流畅,若是你属于交付以后的状态,那么你的甲方必定会来找你麻烦,为了不没必要要的麻烦,请善待你的程序,避免没必要要的Bug,那么接下来就来展现一下这些问题,代码会很是的像,请仔细观看

 

from flask import Flask, request

app = Flask(__name__)

@app.route('/index', methods=['GET', 'POST'])
def index():
    name = request.form['username']  # 注意这里为更改代码
    # name = request.form.get('username')
    pwd = request.form.get('password')
    return 'username = %s, password = %s' % (name, pwd)

if __name__ == '__main__':
    app.run(host='0.0.0.0', debug=True)

 

接下来在看一下若是经过request.form.get('username')这种方式接受前端发送过来的请求参数出现找不到的状况会是友好的吗?

from flask import Flask, request

app = Flask(__name__)

@app.route('/index', methods=['GET', 'POST'])
def index():
    # name = request.form['username']
    name = request.form.get('username')  # 此次是经过get()方法接受数据
    pwd = request.form.get('password')
    return 'username = %s, password = %s' % (name, pwd)

if __name__ == '__main__':
    app.run(host='0.0.0.0', debug=True)

若是表单中传过来同名的键,那么接受结果会如何呢?我在请求中传入了两个username分别是不一样的值

经过返回的结果能够看出,返回给咱们的是第一个找到的username的值,这里若是真的都想获取到,能够经过getlist()方法来接受请求的同名的键

from flask import Flask, request

app = Flask(__name__)

@app.route('/index', methods=['GET', 'POST'])
def index():
    # 经过get方法只能拿到多个同名参数的第一个
    name = request.form.get('username')
    pwd = request.form.get('password')
    # 经过getlist() 能够获取多个
    name_list = request.form.getlist('username')
    return 'username = %s, password = %s, username_list = %s' % (name, pwd, name_list)

if __name__ == '__main__':
    app.run(host='0.0.0.0', debug=True)

注意:确定会有小伙伴,会看见在字符串前面有一个u,这里简单的扩展一下,由于在Python2中,字符串类型默认是两种,一种是str,还有一种Unicode,这里展示的就是Unicode字符串,在Python3中已取消。是一个好吃的鸡肋。不用太在乎,若是之后须要操做它,会在演示如何去使用

若是是请求体的数据不是表单格式的(如json格式),能够经过request.data获取

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

@app.route('/index', methods=['GET', 'POST'])
def index():
    # 若是是请求体的数据不是表单格式的(如json格式),能够经过request.data获取
    json_data = request.data
    return 'json_data = %s' % json_data

if __name__ == '__main__':
    app.run(host='0.0.0.0', debug=True)

 POST请求方式也是能够在地址栏里传递参数的,格式:192.168.3.20:5000/index?age=30&city=harbin

from flask import Flask, request

app = Flask(__name__)

@app.route('/index', methods=['GET', 'POST'])
def index():
    # args是用来提取url中的参数(查询字符串)
    age = request.args.get('age')
    city = request.args.get('city')
    return 'age : %s, city : %s' % (age, city)

if __name__ == '__main__':
    app.run(host='0.0.0.0', debug=True)

一个不重要的注意:还有不少接受方法会在必要的时候引入

 

 

上传文件


用Flask处理文件上传很是的简单,只须要经过一个save()方法,就能够把文件保存到服务器的文件系统中,固然这也是一个很是危险的操做,以后会有介绍,已上传的文件会存储在内存或文件系统中一个临时的位置,你能够经过请求对象的files属性来访问他们,每个上传的文件都会存储在这个字典中,它跟Python中的file对象基本一致。你也能够经过Python的方法来处理文件写入到本地的方法来完成这个操做

这里咱们依然使用Postman来完成这个请求,可是若是你使用的是html页面,必定要确保在HTML表单中设置enctype="multipart/form-data" 属性,否则你的浏览器根本不会发送这个文件,咱们仍是先来完成后台的代码:

from flask import Flask, request

app = Flask(__name__)

@app.route('/', methods=['POST'])
def upload():
    # 使用files属性来访问保存在内存中或者文件系统中一个临时的位置的这个上传文件
    file_obj = request.files.get('pic')
    # 使用save方法来保存刚刚获取的上传文件
    file_obj.save('/home/python/图片/upload.jpg')
    return '文件上传完毕'

if __name__ == '__main__':
    app.run(host='0.0.0.0', debug=True)

给大家展现一下上传的图片,屌丝气质暴露无遗,哈哈哈

能够看出在Flask中上传一个文件真的很简单,接下来,咱们就讨论为何直接使用save()方法会很危险,并且我在官方提供的文档中找到一个很是好的解决方案,能够研究一下,实在看不懂也是无所谓的。文件上传的基本概念实现上很是简单,流程是:

  1. <form> 标签中有定义一个 enctype=multipart/form-data ,而且在里面包含一个 <input type=file> 标签。

  2. 服务端应用经过请求对象上的 files 字典访问文件。

  3. 使用文件的 save() 方法将文件永久地保存在文件系统上的某处。

这样就完成了,可是你永远都没法保证在浏览器访问你网站的那我的,不想搞些事情,好比XSS问题的HTML文件(跨站脚本攻击【XSS】),因此咱们要限制上传文件的后缀,来尽可能保证不要传入一些脚本文件或者别的什么东西。

# coding:utf-8
# request中包含了前端发送过来的全部请求数据
from flask import Flask, request
from werkzeug import secure_filename
import os

# 存储上传文件的路径
UPLOAD_FOLDER = '/home/python/图片/'
# 容许的文件类型
ALLOWED_EXTENSIONS = set(['txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'])

app = Flask(__name__)
# 将路径添加到配置中
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER


# 用来验证用户上传的文件是不是容许的
def allowed_file(filename):
    # 判断文件中是否有. and 用.只截取1次文件名获得的一个列表,选择列表第二个值看是否属于被容许的文件类型
    return '.' in filename and filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS


@app.route('/', methods=['POST'])
def upload():
    # 使用files属性来访问保存在内存中或者文件系统中一个临时的位置的这个上传文件
    file_obj = request.files.get('pic')
    # 判断用户是否上传了文件 和 文件是不是容许的类型
    if file_obj and allowed_file(file_obj.filename):
        filename = secure_filename(file_obj.filename)
        file_obj.save(os.path.join(UPLOAD_FOLDER, filename))
        return '文件上传完毕'
    else:
        return '文件上传失败'
    
    
if __name__ == '__main__':
    app.run(host='0.0.0.0', debug=True)

经过Postman上传一个带有图片的请求,这里咱们从新上传了一个别的文件

这里看出上传文件是没有问题的,如今咱们来测试一下若是上传一个不被容许的文件类型,是否会帮咱们阻拦

这里就能够阻拦咱们不想看到的文件被上传,若是有人想问,文件里包含不少.会不会被阻拦,答案显然是不会,只要是在容许的类型里,都是能够上传的,由于rsplit()是从字符的最后面开始截取的,并且设置了只截取一次 rsplit('.', 1) 【注释 .表明用.截取,1表明截取1次】

相关文章
相关标签/搜索
本站公众号
   欢迎关注本站公众号,获取更多信息