68. WSGI接口

了解了HTTP協(xié)議和HTML文檔养泡,我們其實就明白了一個Web應用的本質(zhì)就是:

瀏覽器發(fā)送一個HTTP請求;
服務器收到請求,生成一個HTML文檔;
服務器把HTML文檔作為HTTP響應的Body發(fā)送給瀏覽器较雕;
瀏覽器收到HTTP響應,從HTTP Body取出HTML文檔并顯示挚币。

所以亮蒋,最簡單的Web應用就是先把HTML用文件保存好,用一個現(xiàn)成的HTTP服務器軟件妆毕,接收用戶請求慎玖,從文件中讀取HTML,返回笛粘。Apache趁怔、Nginx湿硝、Lighttpd等這些常見的靜態(tài)服務器就是干這件事情的。

如果要動態(tài)生成HTML润努,就需要把上述步驟自己來實現(xiàn)关斜。不過,接受HTTP請求任连、解析HTTP請求蚤吹、發(fā)送HTTP響應都是苦力活例诀,如果我們自己來寫這些底層代碼随抠,還沒開始寫動態(tài)HTML呢,就得花個把月去讀HTTP規(guī)范繁涂。

正確的做法是底層代碼由專門的服務器軟件實現(xiàn)拱她,我們用Python專注于生成HTML文檔。因為我們不希望接觸到TCP連接扔罪、HTTP原始請求和響應格式秉沼,所以,需要一個統(tǒng)一的接口矿酵,讓我們專心用Python編寫Web業(yè)務唬复。

這個接口就是WSGI:Web Server Gateway Interface。

WSGI接口定義非常簡單全肮,它只要求Web開發(fā)者實現(xiàn)一個函數(shù)敞咧,就可以響應HTTP請求。我們來看一個最簡單的Web版本的“Hello, web!”:
def application(environ, start_response): start_response('200 OK', [('Content-Type', 'text/html')]) return [b'<h1>Hello, web!</h1>']
上面的application()函數(shù)就是符合WSGI標準的一個HTTP處理函數(shù)辜腺,它接收兩個參數(shù):

environ:一個包含所有HTTP請求信息的dict對象休建;
start_response:一個發(fā)送HTTP響應的函數(shù)。

在application()函數(shù)中评疗,調(diào)用:
start_response('200 OK', [('Content-Type', 'text/html')])
就發(fā)送了HTTP響應的Header测砂,注意Header只能發(fā)送一次,也就是只能調(diào)用一次start_response()函數(shù)百匆。start_response()函數(shù)接收兩個參數(shù)砌些,一個是HTTP響應碼,一個是一組list表示的HTTP Header加匈,每個Header用一個包含兩個str的tuple表示存璃。

通常情況下,都應該把Content-Type頭發(fā)送給瀏覽器矩动。其他很多常用的HTTP Header也應該發(fā)送有巧。

然后,函數(shù)的返回值b'<h1>Hello, web!</h1>'將作為HTTP響應的Body發(fā)送給瀏覽器悲没。

有了WSGI篮迎,我們關心的就是如何從environ這個dict對象拿到HTTP請求信息男图,然后構造HTML,通過start_response()發(fā)送Header甜橱,最后返回Body逊笆。

整個application()函數(shù)本身沒有涉及到任何解析HTTP的部分,也就是說岂傲,底層代碼不需要我們自己編寫难裆,我們只負責在更高層次上考慮如何響應請求就可以了。

不過镊掖,等等乃戈,這個application()函數(shù)怎么調(diào)用?如果我們自己調(diào)用亩进,兩個參數(shù)environ和start_response我們沒法提供症虑,返回的bytes也沒法發(fā)給瀏覽器。

所以application()函數(shù)必須由WSGI服務器來調(diào)用归薛。有很多符合WSGI規(guī)范的服務器谍憔,我們可以挑選一個來用。但是現(xiàn)在主籍,我們只想盡快測試一下我們編寫的application()函數(shù)真的可以把HTML輸出到瀏覽器习贫,所以,要趕緊找一個最簡單的WSGI服務器千元,把我們的Web應用程序跑起來苫昌。

好消息是Python內(nèi)置了一個WSGI服務器,這個模塊叫wsgiref诅炉,它是用純Python編寫的WSGI服務器的參考實現(xiàn)蜡歹。所謂“參考實現(xiàn)”是指該實現(xiàn)完全符合WSGI標準,但是不考慮任何運行效率涕烧,僅供開發(fā)和測試使用月而。

運行WSGI服務

我們先編寫hello.py,實現(xiàn)Web應用程序的WSGI處理函數(shù):

# hello.py

def application(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/html')])
    return [b'<h1>Hello, web!</h1>']```
然后议纯,再編寫一個server.py父款,負責啟動WSGI服務器,加載application()函數(shù):

server.py

從wsgiref模塊導入:

from wsgiref.simple_server import make_server

導入我們自己編寫的application函數(shù):

from hello import application

創(chuàng)建一個服務器瞻凤,IP地址為空憨攒,端口是8000,處理函數(shù)是application:

httpd = make_server('', 8000, application)
print('Serving HTTP on port 8000...')

開始監(jiān)聽HTTP請求:

httpd.serve_forever()```
確保以上兩個文件在同一個目錄下阀参,然后在命令行輸入python server.py來啟動WSGI服務器:

Paste_Image.png

啟動成功后肝集,打開瀏覽器,輸入http://localhost:8000/蛛壳,就可以看到結果了:

Paste_Image.png

在命令行可以看到wsgiref打印的log信息:

Paste_Image.png

按Ctrl+C終止服務器杏瞻。

如果你覺得這個Web應用太簡單了所刀,可以稍微改造一下,從environ里讀取PATH_INFO捞挥,這樣可以顯示更加動態(tài)的內(nèi)容:

# hello.py

def application(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/html')])
    body = '<h1>Hello, %s!</h1>' % (environ['PATH_INFO'][1:] or 'web')
    return [body.encode('utf-8')]```
你可以在地址欄輸入用戶名作為URL的一部分浮创,將返回Hello, xxx!:

![Paste_Image.png](http://upload-images.jianshu.io/upload_images/2184359-7baa197883c95ca2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市砌函,隨后出現(xiàn)的幾起案子斩披,更是在濱河造成了極大的恐慌,老刑警劉巖讹俊,帶你破解...
    沈念sama閱讀 219,366評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件垦沉,死亡現(xiàn)場離奇詭異,居然都是意外死亡劣像,警方通過查閱死者的電腦和手機乡话,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評論 3 395
  • 文/潘曉璐 我一進店門摧玫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來耳奕,“玉大人,你說我怎么就攤上這事诬像∥萑海” “怎么了?”我有些...
    開封第一講書人閱讀 165,689評論 0 356
  • 文/不壞的土叔 我叫張陵坏挠,是天一觀的道長芍躏。 經(jīng)常有香客問我,道長降狠,這世上最難降的妖魔是什么对竣? 我笑而不...
    開封第一講書人閱讀 58,925評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮榜配,結果婚禮上否纬,老公的妹妹穿的比我還像新娘。我一直安慰自己蛋褥,他們只是感情好临燃,可當我...
    茶點故事閱讀 67,942評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著烙心,像睡著了一般膜廊。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上淫茵,一...
    開封第一講書人閱讀 51,727評論 1 305
  • 那天爪瓜,我揣著相機與錄音,去河邊找鬼匙瘪。 笑死铆铆,一個胖子當著我的面吹牛炬转,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播算灸,決...
    沈念sama閱讀 40,447評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼扼劈,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了菲驴?” 一聲冷哼從身側響起荐吵,我...
    開封第一講書人閱讀 39,349評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎赊瞬,沒想到半個月后先煎,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,820評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡巧涧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,990評論 3 337
  • 正文 我和宋清朗相戀三年薯蝎,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片谤绳。...
    茶點故事閱讀 40,127評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡占锯,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出缩筛,到底是詐尸還是另有隱情消略,我是刑警寧澤,帶...
    沈念sama閱讀 35,812評論 5 346
  • 正文 年R本政府宣布瞎抛,位于F島的核電站艺演,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏桐臊。R本人自食惡果不足惜胎撤,卻給世界環(huán)境...
    茶點故事閱讀 41,471評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望断凶。 院中可真熱鬧伤提,春花似錦、人聲如沸懒浮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽砚著。三九已至次伶,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間稽穆,已是汗流浹背冠王。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留舌镶,地道東北人柱彻。 一個月前我還...
    沈念sama閱讀 48,388評論 3 373
  • 正文 我出身青樓豪娜,卻偏偏與公主長得像,于是被迫代替她去往敵國和親哟楷。 傳聞我的和親對象是個殘疾皇子瘤载,可洞房花燭夜當晚...
    茶點故事閱讀 45,066評論 2 355

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn)卖擅,斷路器鸣奔,智...
    卡卡羅2017閱讀 134,669評論 18 139
  • 一、Web開發(fā) Browser/Server模式目前最流行惩阶,簡稱BS架構挎狸。在BS架構下,客戶端只需要瀏覽器断楷,應用程...
    時間之友閱讀 860評論 0 0
  • 在 從零開始搭建論壇(一):Web服務器與Web框架 中我們弄清楚了Web 服務器锨匆、Web 應用程序、Web框架的...
    selfboot閱讀 2,282評論 0 8
  • 全稱為Web Server Gateway Interface冬筒,即 Web服務器網(wǎng)關接口恐锣。是一種標準接口規(guī)范,規(guī)定...
    超net閱讀 3,157評論 0 2
  • 轉載自標點符的《網(wǎng)關協(xié)議學習:CGI、FastCGI学搜、WSGI》 CGI CGI即通用網(wǎng)關接口(Common Ga...
    李紹俊閱讀 1,660評論 0 1