Web开发---请求响应处理与WSGI原理

Web开发

HTTP协议

安装httpd

yum install httpd

协议

cookie

URL组成

HTTP消息

请求

请求消息行:请求方法Method请求路径 协议版本CRLF

请求方法Method

GET       请求获取URL对应的资源
POST     提交数据至服务器端
HEAD     和GET类似,不过不返回消息正文

常见传递信息的方式

响应

响应消息行:协议版本 状态码 消息描述CRLF

Status Code状态码

无状态、有连接和短连接

WSGI

WSGI主要规定了服务器端和应用程序间接口。

WSGI服务器---wsgiref

#返回文本例子
from wsgiref.simple_server import make_server,demo_app

ip = '127.0.0.1'
port = 9999
server = make_server(ip,port,demo_app)  #demo_app应用程序,可调用
server.serve_forever()  #server.handle_request()执行一次

WSGI的作用:

 

WSGI APP应用程序端

#1 函数实现
def application(environ,start_response):
    pass

#2 类实现
class Application:
    def __init__(self,environ,start_response):
        pass

#3 类实现
class Application:
    def __call__(self,environ,start_response): 
    
pass

res_str = b'magedu.com
'
#1 函数实现
def application(environ,start_response):
    return [res_str]

#2 类实现
class Application:
    def __init__(self,environ,start_response):
        pass
    def __iter__(self):#实现此方法,对象即可迭代
        yield res_str

#3 类实现
class Application:
    def __call__(self,environ,start_response):
        return [res_str]

environ

environ是包含Http请求信息的dict对象。

start_response

 

服务器端

 

#返回网页的例子
from wsgiref.simple_server import make_server

def app(environ,start_response):
    status = '200 OK'
    headers = [('Content-Type','text/html;charset=utf-8')]
    start_response(status,headers)
    html = '<h1>chengyu<h1>'.encode("utf-8")
    return [html]   #返回可迭代对象

ip = '127.0.0.1'
port = 9999
server = make_server(ip,port,app)
server.serve_forever()

#测试用命令
$ curl -I http://192.168.10.166:9999/xxx?id=5          #-I 使用HEAD方法
$ curl -X POST http://192.168.10.166:9999/yyy -d '{"x":2}'   #-X 指定方法,-d传输数据

类Flask框架处理

WSGI请求environ处理

 

QUERY_STRING查询字符串的解析

1.编程解析

def app(environ,start_response):
    qstr = environ.get('QUERY_STRING')
    print(qstr)
    if qstr:
        for pair in qstr.split('&'):
            k,_,v = pair.partition('=')
            print("k={},v={}".format(k,v))
    #...

2.使用cgi模块

from cgi import parse_qs

def app(environ,start_response):
    qstr = environ.get('QUERY_STRING')
    print(qstr)
    print(parse_qs(qstr))
    #...

3.使用urllib库

from urllib.parse import parse_qs
def app(environ,start_response):
    qstr = environ.get('QUERY_STRING')
    print(qstr)
    print(parse_qs(qstr))
    #...
#运行结果

id=5&name=wayne&comment=1,2,3&age=6
{'id': ['5'], 'name': ['wayne'], 'comment': ['1,2,3'], 'age': ['6']}

environ的解析---webob库

 

webob简介

webob.Request对象

import webob

def app(environ,start_response):

    request = webob.Request(environ)
    print(request.headers)  #   <webob.headers.EnvironHeaders object at 0x0000000004399320> 类字典容器
    print(request.method)   #   GET
    print(request.path)     #   /
    print(request.query_string)     #   id=5&name=wayne&comment=1,2,3&age=6 类查询字符串
    print(request.params)   #   NestedMultiDict([('id', '5'), ('name', 'wayne'), ('comment', '1,2,3'), ('age', '6')])   所有参数,参数
    #...

MultiDict

from webob.multidict import MultiDict

md = MultiDict()
md.add(1,'magedu')
md.add(1,'com')
md.add('a',1)
md.add('a',2)
md.add('b',3)
md['b'] =4

for pair in md.items():
    print(pair)
print(md.getall('a'))   # [1, 2]
print(md.get('a'))      # 2
# print(md.getone('a'))  #只能有一个值
print(md.get('c'))      # None

webob.Response对象

def app(environ,start_response):
    #...
    res = webob.Response()
    status = res.status
    headers = res.headerlist
    print(status,headers)
    start_response(status,headers)
    html = '<h1>chengyu<h1>'.encode("utf-8")
    return [html]   #返回可迭代对象

#webob.Response类的源码
    def __call__(self, environ, start_response):
        """
        WSGI application interface
        """
        if self.conditional_response:
            return self.conditional_response_app(environ, start_response)

        headerlist = self._abs_headerlist(environ)

        start_response(self.status, headerlist)
        if environ['REQUEST_METHOD'] == 'HEAD':
            # Special case here...
            return EmptyResponse(self._app_iter)
        return self._app_iter

由此可以得到下面代码

def app(environ,start_response):
    #请求处理
    request = webob.Request(environ)
    print(request.headers)  #   <webob.headers.EnvironHeaders object at 0x0000000004399320> 类字典容器
    # print(request.method)   #   GET
    # print(request.path)     #   /
    # print(request.query_string)     #   id=5&name=wayne&comment=1,2,3&age=6 类查询字符串
    # print(request.params)   #   NestedMultiDict([('id', '5'), ('name', 'wayne'), ('comment', '1,2,3'), ('age', '6')])   所有参数,参数
    #...
    #响应处理
    res = webob.Response()  # 200 OK    Content-Type: text/html; charset=UTF-8 Content-Length: 0
    html = '<h1>chengyu<h1>'.encode("utf-8")
    res.body = html
    return res(environ,start_response)   #返回可迭代对象

webob.dec装饰器

 

from wsgiref.simple_server import make_server
from webob.dec import wsgify
import webob

@wsgify
def app(request:webob.Request)-> webob.Response:
    # res = webob.Response('<h1>咸宁欢迎你</h1>')
    res = '咸宁欢迎你'
    # res = '咸宁欢迎你'.encode('utf-8')
    return res

httpd = make_server('127.0.0.1',9999,app)
httpd.serve_forever()

from wsgiref.simple_server import make_server
from webob.dec import wsgify
from webob import Response,Request

class App:
    @wsgify
    def __call__(self, environ:Request):
        return '<h1>北京欢迎你</h1>'

if __name__ == '__main__':
    httpd = make_server('127.0.0.1',9999,App())
    try:
        httpd.serve_forever()
    except KeyboardInterrupt:
        httpd.shutdown()
        httpd.server_close()

做一枚奔跑的老少年!
原文地址:https://www.cnblogs.com/xiaoshayu520ly/p/11226281.html