首頁 > 其他

Python:[1]使用Python開發CGI應用

2019-12-01 05:36:20

我沒有經歷過 CGI 非常火的年代,也一直沒有機會了解 CGI 開發web應用的開發過程,直到 最近聽一位室友很藐視地說 QQ居然還在用C GI 來開發自己的應用, 於是心生出了想了解 CGI 的想法, 於是經過一些學習和調研,也弄清楚了一些問題,和大家分享下.


1

wikipedia中對 CGI 有比較詳盡的描述, 基於自己的理解總結如下.

首先,CGI在web伺服器處理請求中的角色關係如下圖:


2

?CGI 在其中扮演的是在web伺服器和特定語言直譯器之間輸入輸出的協定的角色, 每個來自使用者的請求, web伺服器都會喚起特定語言直譯器的命令列(例如Python), CGI 會作為一種約定來將web伺服器獲得的請求資料(如url,pos t data)等,有選擇地 作為命令列引數來輸入到直譯器的命令列中(標準輸入), 直譯器根據輸入 構造出特定的html作為標準輸出, 此時 CGI 又會對輸出作額外的處理,如加入特定的header(mimetype,cookie等)返回給web伺服器,繼而返回給使用者(web伺服器可能會作額外的處理).這就是一個完整的處理流程.

1

CGI 作為一種標準協定後,各種主流的web伺服器都支援,如 apache, IIS 等, 那麼從上面的處理流程中我們會發現其中的幾個主要缺點:1.對於每個請求,都需要新建立一個直譯器的進程,而進程的建立通常都是比較昂貴的(expens ive)?

2

2.而且,對於指令碼語言,直譯器還需要一定的時間來解釋生成對應的html

3

3.更大機率的 code injection, 因為在cgi指令碼中都是手動地處理html所以更容易引起程式碼注入(當然更多地取決於程式設計師本身)

1

環境如下:Ubuntu 8.101.Apache 2.x2.Python 2.5.2

1

編輯apache組態檔(我的是/etc/apache2/apache2.conf), 加入下面一行:AddHandler cgi-script .py告訴apache來使用CGI協定來解釋python檔案.

1

這裡是個helloworld的應用, 更複雜的可參考 Python CGI.程式碼如下(假設名為tes t.py):#! /usr/bin/env pythonprint "Content-Type: text/html" ?# HTML is followingprint ? ?# blank line, end of headersprint "<html><header><title>Test CGI Python</title></header><body>Hello CGI!</需要注意的是:一個CGI指令碼
由2部分組成, 第一部分是輸出header, 第二部分是輸出常規的html 1.注意 #! /usr/bin/env python 這行程式碼,是說明執行本指令碼所用的程式(這是s hell的相關知識) 2.那麼此時可以在瀏覽器裡看到相應的輸出結果.

1

如果你弄清楚了上面的範例,你就能夠明白 各種web框架(django, cakephp等),都只是簡化和封裝了一些處理的方式,本質還是類似於C GI的處理方式, 即1)header 2)html.想想 django 的 return HttpResponse("<html><header></header><body>Hello</body></html>, 和上述是完全相同的.(HttpRes pons e預設使用text/html)

1

既然這些缺陷是如此明顯,後續的一些web伺服器的設計者或者web開發者便開始著手解決這些問題, 比較重要的有:

fas tcgi 的出現, fas tcgi 的處理流程如下


2

web伺服器和直譯器之間使用TCP或者s ocket來連線,在啟動時會啟動若干個(可以設定)長駐進程來提供請求的服務(減少建立和銷毀進程的開銷), 一個進程可以服務於多個請求(使用多執行緒或者事件驅動,參考 fas tcgis pec).所以 fas tcgi 很好地解決了進程建立/銷毀開銷的問題.

1

另一個思路是類似於apache的mod_perl這樣的解決方式.這種方式是將處理邏輯整合在web伺服器之中, 如下圖:


2

其中你可以在Data Axis (豎軸)上, Content Generator 之前或者之後來加入相應的filter(即module), 來進行特定的處理.

3

通常而言,整合在web伺服器中的module方式,會有更好的效能優勢, 但是因為是整合在web伺服器中, 所以mod_xxx崩潰很有可能會使得web伺服器也崩潰.而 fas tcgi 與web伺服器之間是獨立的進程 一個掛了不會影響另一個.

1

最後,我們回到我的室友提到的那個問題, QQ居然還在用C GI, 通過上面的分析,我們現在應該很明確了, 使用純的CGI並不是一個好的辦法, 因為它的諸多缺陷, 所以可以使用 fas tcgi 或者module的方式.當然,作為最初動態網頁內容處理的始祖, CGI 是具有里程碑式意義的協定,到後來的 fas tcgi, s cgi 等 都是與CGI 的理念相同的.

IT145.com E-mail:sddin#qq.com