10 分离式web框架
wsgiref模块:
将http请求封装成以键值对的形式封装成字典environ:
"PATH_INFO"对应的值为请求文件路径,
“QUERY_STRING”对应的值为get请求发送的数据
“REQUEST+METHOD”对应的值为请求方式。
同时封装一个发送响应格式的函数start_server;通过特定的方式return [ ]返回数据并调用内置方法返回给浏览器。
GET和POST请求:
请求参数的获取:
GET请求参数的传递在url请求文件路径后边拼接显式传输,可以直接在wsgiref模块封装好的environ请求信息字典中以键“QUERY_STRING”取值获取传递的参数;
POST请求参数的传递是在请求信息的请求数据部分,
通过在wsgiref模块封装好的environ请求信息字典中以键“CONTENT_LENGTH”获取参数(bytes类型)长度,然后通过environ["wsgi.input"].read(长度)获取传递的参数(bytes类型)
请求参数的处理:
内置模块(from urllib.parse import parse_qs)
执行parse_qs()进行格式化成字典找到对应的参数值(列表形式,注意get为字符串,post为字节);
具体处理方式:
GET:
|
query_string=environ["QUERY_STRING"] |
#'QUERY_STRING': 'username=zhangsan&userpsd=abc', |
|
query_string=parse_qs(query_string) |
#{ 'username':['zhangsan'],'userpsd':['abc']} |
|
name=query_request["username"][0] |
'zhangsan' |
|
psd=query_request["userpsd"][0] |
'abc' |
POST:
|
leng=int(environ.get('CONTENT_LENGTH',0)) |
#'CONTENT_LENGTH'参数长度 |
|
query_string=environ['wsgi.input'].read(leng) |
#{ 'username':['zhangsan'],'userpsd':['abc']} |
|
query_string=parse_qs(query_string) |
#{ b'username':[b'zhangsan'],b'userpsd':[b'abc']} |
|
name=query_string[b'username'][0].decode("utf-8") |
'zhangsan' |
|
psd=query_string[b'userpsd'][0].decode("utf-8") |
'abc' |
wsgiref封装的请求信息:
|
GET |
{……. 'SERVER_PORT': '8888', 'REMOTE_HOST': '', 'CONTENT_LENGTH': '', 'SCRIPT_NAME': '', 'SERVER_PROTOCOL': 'HTTP/1.1', 'SERVER_SOFTWARE': 'WSGIServer/0.2', 'REQUEST_METHOD': 'GET', 'PATH_INFO': '/auth', 'QUERY_STRING': 'username=zhangsan&userpsd=abc', 'REMOTE_ADDR': '127.0.0.1', 'CONTENT_TYPE': 'text/plain', 'HTTP_HOST': '127.0.0.1:8888', 'HTTP_ACCEPT_LANGUAGE': 'zh-CN,zh;q=0.9', 'wsgi.input': <_io.BufferedReader name=916>…….} |
|
POST |
{…… 'GATEWAY_INTERFACE': 'CGI/1.1', 'SERVER_PORT': '8888', 'REMOTE_HOST': '', 'CONTENT_LENGTH': '29', 'SCRIPT_NAME': '', 'SERVER_PROTOCOL': 'HTTP/1.1', 'REQUEST_METHOD': 'POST', 'PATH_INFO': '/auth', 'QUERY_STRING': '', 'HTTP_ACCEPT_LANGUAGE': 'zh-CN,zh;q=0.9', 'wsgi.input': <_io.BufferedReader name=880>, 'wsgi.errors': <_io.TextIOWrapper name='<stderr>' mode='w' encoding='UTF-8'>, 'wsgi.version': (1, 0), 'wsgi.run_once': False, 'wsgi.url_scheme': 'http', 'wsgi.multithread': True, 'wsgi.multiprocess': False, 'wsgi.file_wrapper': <class 'wsgiref.util.FileWrapper'>} |
客户端浏览器访问:
在浏览器地址栏直接输入地址端口:127.0.0.1:8888
服务器server端python程序(分离版本):
manege.py:
1 from wsgiref.simple_server import make_server #python内置基于socket的服务程序模块 2 from urls import func_mappers #自己封装的请求文件路径与对应操作映射模块 3 4 def application(environ,start_reponse): 5 """ 6 基于wsgiref模块实现客户端请求数据的封装(字典environ)和封装的响应格式发送函数(statr_response)进行服务响应 7 :param environ: wsgiref模块封装好的请求信息字典 8 :param start_reponse: wsgiref模块封装的响应格式发送函数 9 :return: 10 """ 11 path=environ["PATH_INFO"] #通过字典取值获取请求路径信息 12 start_reponse("200 Ok",[("Content","text/html")]) #分装好的函数发送响应格式信息 13 # print(path) 14 # 根据请求文件路径,映射与之对应的函数操作 15 for mapper in func_mappers: 16 if path==mapper[0]: 17 data=mapper[1](environ) 18 else: 19 data=b"Sorry:404 not find" 20 return [data] 21 22 if __name__ == '__main__': 23 httpd=make_server("127.0.0.1",8888,application) 24 httpd.serve_forever()