Day 15 Flask 回传参数

在网页中不可能只是按照设定好的 URL 去取得网页页面,在许多时候都需要带入不同的参数去取得不同的资料,所以这篇就要来讲一下如何接收传入的参数。

HTML Escape

如果需要将使用者传入的值回传给前端,那麽就需要对使用者输入的值参数进行转义,为什麽要这麽搞(费)刚(工)呢?因为不这样处里的话,就会产生 XSS 攻击(Cross Site Scripting,跨站脚本攻击。我也不太懂,用就对了,毕竟资安方面又是另外一个超级大坑了,改天有空再来填坑)。

那要怎麽处里转义呢?

from markupsafe import escape

# 记得实例化 Flask

@app.route('/xss-attack', methods=['GET'])
def XSS_attack():
    return f'Hello {request.values["code"]}'
    
@app.route('/xss-safe', methods=['GET'])
def XSS_safe():
    return f'Hello {escape(request.values["code"])}'

对,用 escape 把输入的值包起来就可以了(记得先 import),接着就让我们来看看有没有使用转义的差别。

首先先用这行网址,来试试没有经过转义会如何。
http://localhost:5000/XSS-attack?code=<script>alert('XSS%20test')</script>

这样就可能会造成 XSS 攻击,现在还只是简单的显示个讯息,如果是将使用者的重要资料秘密的传送给攻击者,後果不堪设想。

反过来用这行网址,来试试经过转义後会如何。
http://localhost:5000/XSS-safe?code=<script>alert('XSS%20test')</script>

在这种情况下,即使攻击者便无法透过这种方式攻击。

JSON

如果现在要开发 API ,需要使用到 JSON 回传,那又要如何回传呢?

在 Python 中虽然有提供 JSON 模组,可以使用 json.dumps() 将资料转换为 JSON 格式。但是,会出现一个问题,什麽问题呢,就来实验一次,先将刚刚的 JSON 改成这样:

import json

@app.route('/json-value', methods=['POST'])
def JSON_value():
    if request.is_json:
        data = request.get_json()
        result = json.dumps(data)
    else:
        result = 'Not JSON Data'
    return result

然後到 POSTMAN 中测试。

发现了吗?没有的话换另外一张。

看到了吗,虽然以为回传了 JSON 格式,但是因为标头没有写回传的是 JSON 格式,所以内容并不被当成 JSON 解析(虽然可以硬改标头)。

为了解决这种情况,Flask 预设如果回传的是 dict,就会转换成 JSON 格式,并将改标头改为 application/json。现在将程序改成这样:

@app.route('/json-value', methods=['POST'])
def JSON_value():
    if request.is_json:
        data = request.get_json()
        result = data
    else:
        result = 'Not JSON Data'
    return result

现在再回到 POSTMAN 测试一次。

看起来是有改成 JSON 格式了,来标头确认看看。

好了,确实有改成使用 JSON 回传了,可是如果是其他格式的资料需要用 JSON 回传的话,还要费功夫将格式转为 dict 才可以回传也太麻烦了。所以 Flask 有提供 jsonify 的方式,可以把 Python 中其他格式的值转换为 JSON 格式再回传。像这样:

@app.route('/json-value', methods=['POST'])
def JSON_value():
    data = ['apple', 'banana', 'car']
    return jsonify(data)

JSON 回传资料大概就这样。

前端页面

虽然还没介绍到前端页面如何使用,不过我还是要稍微讲一下如何传值到前端页面以及快速讲一下如何渲染前端页面。

Flask 要回传(渲染?)一个页面是使用 render_template() 这个 function,而 Flask 会自动到根目录下的 templates 资料夹找页面回传,所以需要在跟目录下建立资料夹并将页面放在里面。架构大概长这样:

ithome
├── templates
│   └── index.html
├── app.py
├── configs.py
├── Pipfile
└── Pipfile.lock

档案内容长这样:

index.html

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8" />
    <title>template value</title>
</head>

<body>
    <h1>Welcome {{ username }}</h1>
</body>

</html>

app.py

from flask import render_template

@app.route('/')
def index():
    return 'Hello'

@app.route('/<user>')
def welcome(user):
    # username 为 KEY 值,html 档会用到;user 为 value,是要带入的值
    return render_template('index.html', username=user)

结果是这样:

那麽就大概这样,下一篇会好好的完整介绍一次前端页面。

大家掰~掰~


<<:  [DAY 15]cog架构用法(2/2)

>>:  Day30:总结

行动商务系统设计与开发!

职训局的课程目前已上了3天课,目前还是在新手学习阶段,初接触visual studio程序,试着使用...

[13th-铁人赛]Day 3:Modern CSS 超详细新手攻略 - Box Model

现在我们手上有了武器(css基本语法),只是刚创建角色拿到的新手包里面那种,所以在打怪前记得先来补充...

[Day 10] 前端页面路由设定 vue-router

开始动工啦~ 今天电脑不在手边,这篇会先在CodeSandBox实作 所以介面会长的跟上一篇的Web...

App 工程师开发设备选用建议

硬体设备每个人偏好不一样,只是这几年关注在 Android App 领域上,分享自身经验供大家工程师...

新新新手阅读 Angular 文件 - Day06

学习目标 本文章将会是阅读官方文件Add navigation with routing 内容所做的...