再运行一次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来结束服务器的运行状态.