web学习之wsgi

from wsgiref.simple_server import make_server


def application(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/html')])
    return [b'<h1>Hello, web!</h1>']


httpd = make_server('', 8080, application)

print('Serving HTTP on port 8000...')
# 开始监听HTTP请求:
httpd.serve_forever()
View Code

          学习笔记之WSGI

WSGI是干吗用的?为何存在?html

由于咱们不但愿接触到TCP链接、HTTP原始请求和响应格式,因此,须要一个统一的接口,让咱们专心用Python编写Web业务。前端

而这个接口就算WSGI:Web Server Gateway Interface。web

make_server的做用是帮咱们封装一些操做:
包括socket对象,绑定(bind),监听(listen)等。后端

便是将以下这些封装打包:浏览器

sk = socket.socket()
 
address = ('127.0.0.1', 8000)
sk.bind(address)
sk.listen(3)

这样子咱们就省了一些功夫去作这些基础性的工做,可是make_server仍是须要ip地址和端口来绑定对象。app

传入的applicadtion参数不须要本身执行,传进去的是函数名,在内部会帮你执行。
以后拿到一个make_server实例化对象传给httpd,再用serve_forever去执行。socket

application的重要参数:
(注意:application是server端,所设置的响应头和响应体都是给客户端看的。)ide

  • .start_response: 设置响应头的参数

  例如:
  start_response('200 OK', [('Content-Type', 'text/html')])
  其字典类型的参数应该放在一个大列表里面,大列表里包括键值对元祖。
  例如('Content-Type', 'text/html')就至关于传了 Content-Type = text / html 给客户端函数

  • environ:封装http解析的信息的参数。

http解析完的数据都放到了environ这个对象里面
想取出environ的值能够经过取出键的值,例如你的子路径是book时能够
用environ['PATH_INFO']。当你相对客户输入不一样的路径作出不一样的响应时,
可也经过if else语句和environ结合来作。学习

def application(environ, start_response):
               start_response('200 OK', [('Content-Type', 'text/html')])
               path = environ['PATH_INFO']
               if path == '/book':
                    return [b'Hello book']
               elif path == '/blog':
                    return [b'Hello web']
               else:
                    return ['<h1>404</h1>'.encode('utf8')]
View Code

优化一下:将客户端发送不一样的请求时返回的不一样的数据这步操做分别写到不一样的函数里边。

def f1():
                return [b'Hello book']
           def f2():
                return [b'Hello web']
           def application(environ, start_response):
               start_response('200 OK', [('Content-Type', 'text/html')])
               path = environ['PATH_INFO']
               if path == '/book':
                    return f1()
               elif path == '/blog':
                    return f2()
               else:
                    return ['<h1>404</h1>'.encode('utf8')]
View Code

咱们也能够传入environ参数给f1()和f2(),这样这两个函数就能够利用environ里面的包装的信息了。

因为子路径有多种,用if else效率并不高,所以咱们能够用循环遍从来优化

代码以下:

def routers():

            urlpatterns = (
                ('/book',f1),
                ('/web',f2),
            )
            return urlpatterns


        def application(environ, start_response):

            print(environ['PATH_INFO'])
            path=environ['PATH_INFO']
            start_response('200 OK', [('Content-Type', 'text/html')])


            urlpatterns = routers()
            func = None
            for item in urlpatterns:
                if item[0] == path:
                    func = item[1]
                    break
            if func:
                return func(environ)
            else:
                return ["<h1>404</h1>".encode("utf8")]
View Code

过程:将子路径和所对应的函数都给封装到一个元祖里面,而后将这些元祖封装到另外一个元祖里面
   给urlpaytterns。将这些信息整合在routers函数里面,在application函数里面用for循环遍历
      routers函数返回的信息,当item[0]跟客户端(浏览器)输入的一致时,就能够调用item[1]传递
   给fun,而后break跳出循环接着执行下面的代码,不然继续循环遍历。

优势:1.添加新的子路径时不用继续死套if else语句,起了简化做用。
      2.返回数据变活了

优化完源码

from wsgiref.simple_server import make_server


def f1(environ):
    return [b'Hello book']
def f2(environ):
    return [b'Hello web']

def routers():
    urlpatterns = (
        ('/book', f1),
        ('/web', f2),
    )
    return urlpatterns


def application(environ, start_response):
    # 经过environ封装成一个全部请求信息的对象
    # start_response能够很方便的设置响应头
    print(environ['PATH_INFO'])
    path = environ['PATH_INFO']
    start_response('200 OK', [('Content-Type', 'text/html')])

    urlpatterns = routers()
    func = None
    for item in urlpatterns:
        if item[0] == path:
            func = item[1]
            break
    if func:
        return func(environ)
    else:
        return ["<h1>404</h1>".encode("utf8")]

#封装socket对象以及准备过程(socket,bind,listen)
httpd = make_server('', 8000, application)

print('Serving HTTP on port 8000...')
# 开始监听HTTP请求:
httpd.serve_forever()
View Code

如今,咱们完成一个在浏览器页面显示时间的小做业,需求:当咱们在浏览器端输入127.0.0.1:xxxx/

current_time时,在浏览器页面打印出当前时间。

  • xxxx表示当前运行的端口号

 


 

做业答案区:

先创建一个HTML文件,内容以下:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<h1>current_time:  !cur_time!</h1>

</body>
</html>
View Code
接着在后端接受前端文件,对其进行修改返回给浏览器便可。代码以下:

from wsgiref.simple_server import make_server
import time

def routers():

    urlpatterns = (
        ('/current_time',current_time),
    )
    return urlpatterns

def current_time(request):


    cur_time = time.ctime(time.time())  # ctime里面传一个时间戳 而time.time()就算时间戳
    f = open('current_time.html','rb')
    data = f.read()

    data = str(data,'utf8').replace('!cur_time!',str(cur_time))

    return [data.encode('utf8')]


def application(environ, start_response):

    print(environ['PATH_INFO'])
    path=environ['PATH_INFO']
    start_response('200 OK', [('Content-Type', 'text/html')])


    urlpatterns = routers()
    func = None
    for item in urlpatterns:
        if item[0] == path:
            func = item[1]
            break
    if func:
        return func(environ)
    else:
        return ["<h1>404</h1>".encode("utf8")]

httpd = make_server('', 8084, application)

print('Serving HTTP on port 8084...')

# 开始监听HTTP请求:

httpd.serve_forever()
View Code

 

这是第一次写博客记录学习~   多谢支持~~

相关文章
相关标签/搜索