zoukankan      html  css  js  c++  java
  • 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()

    做一枚奔跑的老少年!
  • 相关阅读:
    生产上第一使用线程池后的总结与反思
    20190407
    20190403
    Asp.net MVC中的ViewData与ViewBag
    easyui datagrid分页
    EF从数据库更新模型更新不到新表
    C语言 笔记(函数)
    python 写100~1000以内水仙花数
    python 求前n项阶乘的和
    python 写九九乘法表
  • 原文地址:https://www.cnblogs.com/xiaoshayu520ly/p/11226281.html
Copyright © 2011-2022 走看看