您好,登錄后才能下訂單哦!
這篇文章主要為大家展示了“Python中的知識點有哪些”,內容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領大家一起研究并學習一下“Python中的知識點有哪些”這篇文章吧。
最早的時候,WEB就是一些靜態(tài)文件。由開發(fā)人員通過編輯器直接編輯生成靜態(tài)的HTML頁面,如果要修改WEB頁面的內容或布局,就得編輯這些靜態(tài)的HTML文件。早期的時候就是這么來玩的,是不是讓人著實不爽?
由于靜態(tài)WEB頁面無法與用戶進行交互(提交表單等操作)。為了解決這一問題,人們開發(fā)出了一種稱為CGI(Common Gateway Interface)的技術,使用 C/C++
編寫。
由于WEB應用的特點是頻繁更新,用低級語言非常不適合高效地開發(fā)。而腳本語言(JSP、PHP)由于開發(fā)效率高,與HTML結合緊密,因此,迅速取代了CGI模式。JSP使用Java編寫腳本,而PHP則是開源的腳本語言。
最早的動態(tài)頁面是CGI實現(xiàn)的,CGI是怎么工作的?當請求某個地址的時候,http服務器會啟動一個外部程序,并且把外部程序的輸出返回給用戶。CGI規(guī)范了http和外部程序的通信方式。
輸入:通過環(huán)境變量
輸出:通過標準輸出
CGI的缺點:
并發(fā)模式是多進程
進程由http服務器管理
基于CGI以上的缺點,由此衍生出了FastCGI技術,把進程管理交給其他服務來處理。http服務器把http協(xié)議轉化成fastcgi協(xié)議,通過socket發(fā)送給FastCGI守護進程。這樣并發(fā)模型變得多種多樣,進程管理由FastCGI實現(xiàn),單一原則。
另一個分支就是由cgi發(fā)展的wsgi技術。接下來就看看wsgi。
Web框架的主要關鍵點:
路由
Request解析
Response封裝
Web服務器網(wǎng)關接口(WSGI)是Python Web應用程序框架和Web服務器之間標準接口的規(guī)范。
在Python Web應用程序的早期,由于沒有統(tǒng)一的標準,將Web應用程序框架連接到Web服務器是不容易的。Python Web應用程序是用于工作的,具體是通過運用現(xiàn)有的CGI、FastCGI或mod_python(Apache)標準之一。這意味著在一個Web服務器上工作的應用程序可能無法在另一個Web服務器上工作。換言之,統(tǒng)一的應用程序與Web服務器之間的互操作性沒有了。
WSGI通過在服務器和Web應用框架之間指定一個簡單但統(tǒng)一的接口來解決這個問題,從而允許移植Web應用程序。
WSGI指定了兩個方面:服務器(或網(wǎng)關)端,以及應用程序或框架端。WSGI請求得到了以下處理:
服務器端執(zhí)行應用程序,給應用程序提供一個環(huán)境和一個回調函數(shù)。
應用程序處理請求,并使用所提供的回調函數(shù)返回響應給服務器。
流程如下:
wsgi兩部分組成:容器,應用。也可以把容器稱為網(wǎng)關或服務器。容器實現(xiàn)了協(xié)議轉換,由http協(xié)議到wsgi協(xié)議的轉換;應用用來處理業(yè)務邏輯。
容器和應用怎么通信呢?FastCGI通過socket;wsgi的容器和應用通過函數(shù)調用進行通信。什么情況下可以通過函數(shù)調用實現(xiàn)通信?同一進程內可以實現(xiàn)函數(shù)調用,wsgi的容器和應用是運行在同一進程之中。
常用的wsgi容器:gunicorn,uWSGI。
說了這么多,還是看個簡單的例子吧,看看wsgi是如何工作的。接下來實現(xiàn)一個helloworld的程序。
wsgi application應該是一個callable對象。函數(shù)是可調用的,如果一個類有__call__
方法,也是可調用的。
wsgi函數(shù)的書寫有一定的要求,它的函數(shù)簽名一般如下,比較固定:
def application(environ, start_response): ''' # 函數(shù)傳入的參數(shù)是有規(guī)定的: # environ:environ變量是從服務器傳遞到應用程序的環(huán)境變量的字典,如請求內容等; # 由公共網(wǎng)關接口(CGI)規(guī)范定義。WSGI在其規(guī)范中規(guī)定了一些環(huán)境變量受托者 # start_response:一個可調用對象,其提供一個從服務器端到應用程序端的回調,從而開啟服務器端的 # 響應處理。它必須有兩個位置參數(shù)。第一個應該是具有整型狀態(tài)嗎的狀態(tài)字符串,第二個是一個(header_name, header_value)列表,其是描述HTTP頭響應的元組。 ''' pass
上述函數(shù)傳入的參數(shù)是有規(guī)定的:
environ
:environ
變量是從服務器傳遞到應用程序的環(huán)境變量的字典,如請求內容等;由公共網(wǎng)關接口(CGI)規(guī)范定義。WSGI在其規(guī)范中規(guī)定了一些環(huán)境變量受托者
start_response
:一個可調用對象,其提供一個從服務器端到應用程序端的回調,從而開啟服務器端的響應處理。它必須有兩個位置參數(shù)。第一個應該是具有整型狀態(tài)嗎的狀態(tài)字符串,第二個是一個(header_name, header_value
)列表,其是描述HTTP頭響應的元組。
要了解更多的WSGI規(guī)范,可以看看PEP 3333提案。
開始寫:
def application(environ, start_response): body = 'hello world' status = '200 OK' headers = [ ('content-type', 'text/plain'), ('content-length', str(len(body))) ] start_response(status, headers) return [body.encode()] # 以上代碼只有應用,沒有容器; if __name__ == '__main__': # 引入wsgi容器 from wsgiref.simple_server import make_server server = make_server('0.0.0.0', 8000, application) try: server.serve_forever() except KeyboardInterrupt: server.shutdown()
運行以上代碼,并在瀏覽器上進行訪問:
[lavenliu@VM_113_230_centos 12-web]$ python wsgi01.py 183.192.25.121 - - [13/Oct/2018 18:48:08] "GET / HTTP/1.1" 200 11 183.192.25.121 - - [13/Oct/2018 18:48:09] "GET /favicon.ico HTTP/1.1" 200 11 183.192.25.121 - - [13/Oct/2018 18:48:09] "GET /favicon.ico HTTP/1.1" 200 11
也可以通過curl命令行工具進行訪問:
curl -XPOST http://127.0.0.1:8000 -d '{"a": 1}'
接下來使用gunicorn容器來運行上述代碼:
# 首先安裝gunicorn pip install gunicorn # 接著運行wsgi01.py的application應用 [lavenliu@VM_113_230_centos 12-web]$ gunicorn -b 0.0.0.0 wsgi01:application [2018-10-13 18:55:38 +0800] [18359] [INFO] Starting gunicorn 19.6.0 [2018-10-13 18:55:38 +0800] [18359] [INFO] Listening at: http://0.0.0.0:8000 (18359) [2018-10-13 18:55:38 +0800] [18359] [INFO] Using worker: sync [2018-10-13 18:55:38 +0800] [18397] [INFO] Booting worker with pid: 18397
通常在開發(fā)的時候,使用wsgiref就行了,如果在生產(chǎn)中,可以使用第三方的wsgi容器。
上面的代碼中,如果想看environ中的內容,可以在上述代碼中添加如下的代碼:
for k, v in environ.items(): print('{} => {}'.format(k, v)) # 完整的代碼如下: # coding: utf-8 def application(environ, start_response): for k, v in environ.items(): print('{} => {}'.format(k, v)) body = 'hello world' status = '200 OK' headers = [ ('content-type', 'text/plain'), ('content-length', str(len(body))) ] start_response(status, headers) return [body.encode()] # 以上只有應用代碼,沒有容器 if __name__ == '__main__': from wsgiref.simple_server import make_server server = make_server('0.0.0.0', 8000, application) try: server.serve_forever() except KeyboardInterrupt: server.shutdown()
如果再次運行代碼,會有如下的輸出:
wsgi.input => <gunicorn.http.body.Body object at 0x7fe20286c198> HTTP_ACCEPT_ENCODING => gzip, deflate HTTP_ACCEPT_LANGUAGE => zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3 SERVER_PORT => 8000 RAW_URI => / REMOTE_PORT => 16252 HTTP_USER_AGENT => Mozilla/5.0 (Windows NT 6.3; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0 wsgi.file_wrapper => <class 'gunicorn.http.wsgi.FileWrapper'> REMOTE_ADDR => 183.192.25.121 wsgi.version => (1, 0) wsgi.url_scheme => http HTTP_HOST => 115.159.125.96:8000 wsgi.multithread => False HTTP_ACCEPT => text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 wsgi.multiprocess => False QUERY_STRING => SERVER_SOFTWARE => gunicorn/19.6.0 SERVER_PROTOCOL => HTTP/1.1 PATH_INFO => / HTTP_CONNECTION => keep-alive REQUEST_METHOD => GET wsgi.run_once => False wsgi.errors => <gunicorn.http.wsgi.WSGIErrorsWrapper object at 0x7fe20286c1d0> SERVER_NAME => 0.0.0.0 HTTP_CACHE_CONTROL => max-age=0 SCRIPT_NAME => gunicorn.socket => <socket.socket fd=10, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('10.105.113.230', 8000), raddr=('183.192.25.121', 16252)>
environ中有一個QUERY_STRING的key,我們可以打印該信息:
[lavenliu@VM_113_230_centos 12-web]$ cat wsgi01.py # coding: utf-8 def application(environ, start_response): print(environ.get('QUERY_STRING')) body = 'hello world' status = '200 OK' headers = [ ('content-type', 'text/plain'), ('content-length', str(len(body))) ] start_response(status, headers) return [body.encode()] # 以上只有應用代碼,沒有容器 if __name__ == '__main__': from wsgiref.simple_server import make_server server = make_server('0.0.0.0', 8000, application) try: server.serve_forever() except KeyboardInterrupt: server.shutdown()
在瀏覽器的URL地址欄里輸入:
http://115.159.125.96:8000?name=lavenliu&age=25
運行效果如下:
[lavenliu@VM_113_230_centos 12-web]$ gunicorn -b 0.0.0.0 wsgi01:application [2018-10-13 19:15:36 +0800] [20609] [INFO] Starting gunicorn 19.6.0 [2018-10-13 19:15:36 +0800] [20609] [INFO] Listening at: http://0.0.0.0:8000 (20609) [2018-10-13 19:15:36 +0800] [20609] [INFO] Using worker: sync [2018-10-13 19:15:36 +0800] [20647] [INFO] Booting worker with pid: 20647 name=lavenliu&age=25 # 獲得的來自客戶端的輸入
上面的輸出中,
name=lavenliu&age=25 # 獲得的來自客戶端的輸入
接下來就是解析來自客戶端的輸入,解析這件事也不是很困難,不過有標準庫來處理這個解析的工作,引入標準庫:
from urllib.parse import parse_qs from html import escape parse_qs('name=lavenliu&age=25') # 返回的value是列表,因為有可能key有同名的
執(zhí)行結果如下:
{'age': ['25'], 'name': ['lavenliu']}
接下來的代碼如下:
[lavenliu@VM_113_230_centos 12-web]$ cat wsgi02.py # coding: utf-8 from urllib.parse import parse_qs from html import escape def application(environ, start_response): params = parse_qs(environ.get('QUERY_STRING')) name = params.get('name', ['anon'])[0] body = 'hello {}'.format(name) # 如果用戶在瀏覽器里輸入非法的東東時,可能會有問題 status = '200 OK' headers = [ ('content-type', 'text/html'), ('content-length', str(len(body))) ] start_response(status, headers) return [body.encode()] # 以上只有應用代碼,沒有容器 if __name__ == '__main__': from wsgiref.simple_server import make_server server = make_server('0.0.0.0', 8001, application) try: server.serve_forever() except KeyboardInterrupt: server.shutdown()
如果用戶在瀏覽器這樣輸入,就有可能有問題:
http://115.159.125.96:8001?name=<script type='text/javascript'>alert('f**k it')</script> # chrome瀏覽器則沒有問題,它會檢測到這個輸入有問題;如果在IE6上可能就會執(zhí)行上述代碼。 Navigated to http://115.159.125.96:8001/?%3Cscript%20type=%27text/javascript%27%3Ealert(%27f**k%20it%27)%3C/script%3E ?name=<script type='text/javascript'>alert('f**k it')</script>:1 The XSS Auditor refused to execute a script in 'http://115.159.125.96:8001/?name=%3Cscript%20type=%27text/javascript%27%3Ealert(%27f**k%20it%27)%3C/script%3E' because its source code was found within the request. The auditor was enabled as the server sent neither an 'X-XSS-Protection' nor 'Content-Security-Policy' header. Navigated to http://115.159.125.96:8001/?name=%3Cscript%20type=%27text/javascript%27%3Ealert(%27f**k%20it%27)%3C/script%3E # 在火狐瀏覽器就能通過,不會報錯 # IE11版本則沒有這個問題
以上是“Python中的知識點有哪些”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業(yè)資訊頻道!
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內容。