Flask接收请求

flask 通过request方法来接收前端请求过来的参数,具体常用的方法:

方法

描述

args

get请求的方法

data

原始的请求数据

form

接收post请求方法的参数

files

接收文件请求参数

method

请求方式,加载页面的请求都是get请求

referer

请求来源

host

主机

host_url

主机地址

以上数据存放在url或者请求头部。

表单请求

就是利用HTML的表单和组件向服务器发起请求,在过程当中需要对form标签设置以下参数

参数

描述

method

请求方式,默认是GET

action

请求的地址,就是将数据提交到哪里,默认提交到当前路由

enctype

用来表述请求数据不单单是字符

注意:form表单的元素必须有name标签,否者前端请求不发送数据。

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <form method="get" action="/index/">
            <input type="text">
            <button>搜索</button>
        </form>
    </body>
</html>

POST请求

post请求用于向服务器提交数据,flask视图函数默认只接受get请求数据,post数据需要设置,并且使用request.form接受post数据

@app.route("/add_page/",methods = ["GET","POST"])
def add_page():
    if request.method == "POST":
        #获取post提交的数据
        data = request.form
        p_name = data.get("p_name")
        gender = data.get("gender")
        age = data.get("age")
        education = data.get("education")
        department = data.get("department")
        position = data.get("position")
        #定义工号
        number = Person.query.all()[-1].id+1
        #定义工资
        m = 5000  # 基本工资
        m_1 = 1000  # 职级工资

        if position == "部长":
            m_1 = 1000 * 4
        elif position == "经理":
            m_1 = 1000 * 3
        elif position == "组长":
            m_1 = 1000 * 2
        money = m + m_1

        #保存数据
        p = Person()
        p.work_number = str(number).zfill(8)
        p.p_name = p_name
        p.gender = gender
        p.age = age
        p.education = education
        p.department = department
        p.position = position
        p.money = money
        p.save()

    return render_template("add_page.html")

post数据需要在form标签上设置method属性

<form method="post">
    <div>
        <label>姓名:</label>
        <input type="text" name="p_name">
    </div>
    <div>
        <label>性别:</label>
         <input type="radio" value="男" name="gender">男
         <input type="radio" value="女" name="gender">女
    </div>
    <div>
        <label>年龄</label>
        <input type="number" name="age">
    </div>
    <div>
        <label>学历</label>
        <input type="text" name="education">
    </div>
    <div>
        <label>部门</label>
        <select name="department">
            <option value="人事部">人事部</option>
            <option value="人事部">财务部</option>
            <option value="人事部">后勤部</option>
            <option value="人事部">研发部</option>
            <option value="人事部">销售部</option>
            <option value="人事部">安保部</option>
            <option value="人事部">市场部</option>
            <option value="人事部">采购部</option>
        </select>
    </div>
    <div>
        <label>职位</label>
        <select name="position">
            <option value="部长">部长</option>
            <option value="经理">经理</option>
            <option value="组长">组长</option>
            <option value="职员">职员</option>
        </select>
    </div>
    <div>
        <input type="submit" value="提交">
    </div>
</form>

flask 表单文件提交

前端需要注意在form标签上添加enctype属性

<form method="post" enctype="multipart/form-data">
    <div class="form-group">
        <label class="control-label">标题:</label>
        <input class="form-control" type="text" name="title" placeholder="标题">
    </div>
    <div class="form-group">
        <label class="control-label">作者:</label>
        <input class="form-control" type="text" name="author" placeholder="作者">
    </div>
    <div class="form-group">
        <label class="control-label">内容:</label>
        <textarea class="form-control ckeditor" name="content"></textarea>
    </div>
    <div class="form-group">
        <label class="control-label">图片:</label>
        <input type="file" name="picture">
    </div>
    <div class="form-group">
        <button class="btn btn-primary btn-block">提交</button>
    </div>
</form>

后端需要request.files接收数据,并且在保存图片的同时,将路径保存到数据库

@app.route("/add_news/",methods = ["GET","POST"])
def add_news():
    if request.method == "POST":
        data = request.form
        title = data.get("title")
        author = data.get("author")
        content = data.get("content")

        #保存图片
        picture = request.files.get("picture")
        #图片名称
        filename = picture.filename
        #图片保存路径
        path = os.path.join(
            os.path.dirname(
                os.path.abspath(__file__)
            ),"static"
        )
        file_path = os.path.join("img",filename)
        save_path = os.path.join(path,file_path)
        picture.save(save_path) #保存

        news = News()
        news.title = title
        news.author = author
        news.content = content
        news.picture = file_path
        news.public_time = datetime.datetime.now()
        news.save()
        return redirect8 #跳转
    return render_template("add_news.html")

ajax技术

常规web请求,总是会刷新页面,这个事情不是很好。

以用户名 重复校验为例子

前端可以通过js或者jq构建ajax结构

$.ajax({
    url: "/has_user/?username="+value, //请求的地址  类似form的action
    type: "get", //请求的方法  类似form表单的method
    data: "",  // 类似input的数据
    success: function (data) {
        console.log(data);
        $("#error").text(data["d"])
    }, //请求成功执行的函数,会接收返回的数据
    error: function (error) {
        console.log(data)
    } //请求失败执行的函数,会接收返回的数据
})

注意ajax通常不会和页面共用一个视图,因为标准ajax数据返回格式是json。

@app.route("/demo/")
def ajax_demo():
    """
    返回页面
    :return:
    """
    return render_template("ajax_demo.html")

from flask import jsonify #json

@app.route("/has_user/")
def has_user():
    """
    处理ajax,数据返回到请求ajax地址的js当中
    :return:
    """
    user = request.args.get("username")
    p = Person.query.filter(Person.username == user).first()
    result = {"l":[1,2,3]}
    if p:
       result["d"] =  "用户名已经存在"
    else:
        result["d"] = "用户名可以使用"
    return jsonify(result)

Cookie和Session

python flask接收get请求变量的中文参数乱码 flask接收post请求_数据

Cookie(曲奇)机制:在用户请求服务器的时候,服务器下发身份校验到用户本地,之后用户携带这个校验数据请求服务器其他地方,服务器通过这个校验数据识别用户身份,这种机制就是cookie机制。

HTTP的每次请求是独立的,和上一次,下一次请求没有关系,所以需要采用上述的cookie机制来进行身份校验。

由于cookie保存在本地,就会出现以下情况:

1、可以被拒绝

2、可以被仿照

3、可以被劫持

使用cookie步骤:

1、下发cookie(生成cookie)

cookie必须通过response对象进行下发,render_template返回的是一个字符串对象,需要使用make_response对象进行转换

response.set_cookie 可以设置cookie

参数

描述

key

cookie的键

value

cookie的值

max_age

寿命,有效期,秒 60*15 默认关闭浏览器,cookie过期

expires

过期时间,具体的时间节点,和max_age冲突

path

cookie起作用的范围 默认是 /,也可以设置其他路由

domain

起作用的网站,或者域名 www.baidu.com

secure

是否采用用安全的cookie传输方式

httponly

只使用http协议,不使用https协议

samesite

起作用的url

from flask import make_response
@app.route("/cookieExm/")
def cookieExm():
    response = make_response(render_template("empty.html"))
    response.set_cookie("name","laobian")
    return response

2、携带cookie请求,浏览器会自动安装cookie设置携带cookie去请求。

3、校验cookie

获取

比对

@app.route("/getcookie/")
def getcookie():
    name = request.cookies.get("hello")
    if name and name == "laobian":
        response = make_response("laobian")
    else:
        response = make_response("校验失败")
    return response

案例:

python flask接收get请求变量的中文参数乱码 flask接收post请求_python_02

登录案例

密码加密

import hashlib

def setPassWord(password):
    md5 = hashlib.md5()
    md5.update(password.encode())
    return md5.hexdigest()

注册

@app.route("/register/",methods=["GET","POST"])
def register():
    """
    密码需要加密
    """
    if request.method == "POST":
        #接收post数据
        username = request.form.get("username")
        password = request.form.get("password")

        #校验用户名是否重复
        user = Person.query.filter_by(username = username).first()
        if not user:
            p = Person()
            p.username = username
            #密码加密
            p.password = setPassWord(password)
            #保存数据
            p.save()
            #跳转到登录页面
            return redirect("/login/")
    return render_template("register.html")

登录

@app.route("/login/",methods=["GET","POST"])
def login():
    if request.method == "POST":
        # 接收post数据
        username = request.form.get("username")
        password = request.form.get("password")

        password = setPassWord(password) #对请求密码加密
        user = Person.query.filter_by(username = username,password = password).first() #校验用户名和密码
        if user:
            #设置cookie
            respone = redirect("/index/") #本身就是response对象
            respone.set_cookie("username",user.username) #设置cookie
            return respone #返回响应
    return render_template("login.html")

首页

登录校验

from functools import wraps

def is_login(fun):
    @wraps(fun)
    def inner(*args,**kwargs):
        username = request.cookies.get("username")
        if username and Person.query.filter_by(username=username).first():
            return fun(*args,**kwargs) #返回被装饰函数的功能
        else:
            return redirect("/login/") #否者返回登录页面
    return inner

退出

@app.route("/logout/")
def logout():
    """
    退出就是删除cookie的过程
    :return:
    """
    response = redirect("/login/")
    response.delete_cookie("username") #删除客户浏览器本地cookie	
    return response