一、html
首先了解下,Web應用的本質,大致以下:python
一、瀏覽器發送一個HTTP請求;瀏覽器
二、服務器收到請求,生成一個HTML文檔;服務器
三、服務器把HTML文檔做爲HTTP響應的Body發送給瀏覽器;app
四、瀏覽器收到HTTP響應,從HTTP Body取出HTML文檔並顯示。函數
以上這些操做通常都有現成的HTTP服務器軟件,接收用戶請求,從文件中讀取HTML,返回。
如,Apache、Nginx、Lighttpd等這些常見的靜態服務器就是幹這件事情的。
整個過程接受HTTP請求、解析HTTP請求、發送HTTP響應都有這些服務器來完成,不過前提
是這些頁面都是現成生成好的html靜態頁面。spa
二、code
若是要動態生成HTML,就須要把上述步驟本身來實現。正確的作法是底層代碼由專門的服務
器軟件實現,咱們用Python專一於生成HTML文檔。由於咱們不但願接觸到TCP鏈接、HTTP
原始請求和響應格式,因此,須要一個統一的接口,讓咱們專心用Python編寫Web業務(引用網上描述)router
接口WSGI(Web Server Gateway Interface),就實現了這些功能,他的定義很是簡單,只須要
Web開發者實現一個函數,就能夠響應HTTP請求。server
如:
1 def application(environ, start_response): 2 start_response('200 OK', [('Content-Type', 'text/html')]) 3 return '<h1>Hello, world!</h1>'
environ:一個包含全部HTTP請求信息的dict對象。
start_response:一個發送HTTP響應的函數。
有了WSGI,咱們關心的就是如何從environ這個dict對象拿到HTTP請求信息,而後構造HTML,經過start_response()發送Header,最後返回Body。
整個application()函數自己沒有涉及到任何解析HTTP的部分,也就是說,底層代碼不須要咱們本身編寫,咱們只負責在更高層次上考慮如何響應請求就能夠了。
咱們如今用Python內置的WSGI服務器,這個模塊叫wsgiref 來驗證下整個過程。
def application(environ, start_response): start_response('200 OK', [('Content-Type', 'text/html')]) return '<h1>Hello, world!</h1>' from wsgiref.simple_server import make_server # 建立一個服務器,IP地址爲空,端口是8000,處理函數是application: httpd = make_server('', 8000, application) print "Serving HTTP on port 8000..." # 開始監聽HTTP請求: httpd.serve_forever()
啓動成功後,打開瀏覽器,輸入http://localhost:8000/,就能夠看到結果了。
三、不過通常實際應用中會稍微加工,這樣更符合面向對象的原則。
請看如下實例:
#!/usr/bin/env python # -*- coding:utf-8 -*- # Author:Eric.yue from wsgiref.simple_server import make_server class WSGIapp(object): def __init__(self): self.path_info = {} def route(self,path=None): def wrapper(application): self.path_info[path] = application return wrapper def __call__(self,environ,start_response): path = environ['PATH_INFO'] if path in self.path_info: status = '200 OK' response_headers = [('Content-Type','text/plain')] start_response(status,response_headers) return self.path_info[path]() else: status = '404 Not Found' response_headers = [('Content-Type','text/plain')] start_response(status,response_headers) return '404 Not Found!' app = WSGIapp() @app.route('/') #register router def index(): return ['index'] @app.route('/hello') #register router def hello(): return ['hello world'] ''' app 爲函數,這裏__call__的做用就是把類實例當作一個函數來執行 有時候爲了加入權限須要再執行一層middleware middleware 中間件是一類特殊的程序,能夠在容器和應用之間幹一些事 ''' class Auth(object): def __init__(self,app): self.app = app def __call__(self,environ, start_response): #TODO something return self.app(environ, start_response) Auth_app = Auth(app) httpd = make_server('',8888,Auth_app) httpd.serve_forever()
OVER!