WSGI: 解析GET请求

再运行一次environment.py脚本, 这次用以下链接方式进行访问:

http://localhost:8051/?age=10&hobbies=software&hobbies=tunning

在浏览器抛出的响应信息中查看 environ字典中的QUERY_STRING 和 REQUEST_METHOD 变量:

QUERY_STRING: age=10&hobbies=software&hobbies=tunning
REQUEST_METHOD: GET
当请求方式是GET时, 表单变量将会作为URL的一部分一起发送, 即URL中 ? 之后的部分.

注意 hobbies变量出现了两次. 当表单内有checkbox时会出现, 另一中情况是用户在URL中输入多次相同的变量.

可以写代码来解析请求字符串并检索这些值, 但是更简单的方式是实用 cgi.parse_qs() 函数, 它会返回一个以数组形式存放这些值的字典.

要时刻注意用户的输入信息, 防止脚本注入. 函数 cgi.escape() 可以用来作这个.


以下脚本中的HTML 表单指示浏览器作 GET 请求(method="get"):

#!/usr/bin/env python

from wsgiref.simple_server import make_server
from cgi import parse_qs, escape

html = """
<html>
<body>
   <form method="get" action="">
        <p>
           Age: <input type="text" name="age" value="%(age)s">
        </p>
        <p>
            Hobbies:
            <input
                name="hobbies" type="checkbox" value="software"
                %(checked-software)s
            > Software
            <input
                name="hobbies" type="checkbox" value="tunning"
                %(checked-tunning)s
            > Auto Tunning
        </p>
        <p>
            <input type="submit" value="Submit">
        </p>
    </form>
    <p>
        Age: %(age)s<br>
        Hobbies: %(hobbies)s
    </p>
</body>
</html>
"""

def application (environ, start_response):

    # 返回以数组形式存放值的字典
    d = parse_qs(environ['QUERY_STRING'])
    # 由于一个变量可以有几个值, 所以将一个数组设置为默认值.
    age = d.get('age', [''])[0] # 返回第一个 age 值
    hobbies = d.get('hobbies', []) # 返回一个 hobbies 数组

    # 防止用户进行脚本注入
    age = escape(age)
    hobbies = [escape(hobby) for hobby in hobbies]

    response_body = html % { # 嵌入上面的html模板
        'checked-software': ('', 'checked')['software' in hobbies],
        'checked-tunning': ('', 'checked')['tunning' in hobbies],
        'age': age or 'Empty',
        'hobbies': ', '.join(hobbies or ['No Hobbies?'])
    }

    status = '200 OK'

    # 现在内容类型变成 text/html
    response_headers = [
        ('Content-Type', 'text/html'),
        ('Content-Length', str(len(response_body)))
    ]

    start_response(status, response_headers)
    return [response_body]

httpd = make_server('localhost', 8051, application)

# 用 serve_forever() 代替 handle_request() 
httpd.serve_forever()

现在访问一下 http://localhost:8051

由于将脚本中的服务器运行变成了 server_forever, 所以它会一直处于运行状态. 我们可以用Ctrl-C来结束服务器的运行状态.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值