首頁  >  文章  >  後端開發  >  Python的web伺服器相關知識點

Python的web伺服器相關知識點

巴扎黑
巴扎黑原創
2017-06-23 11:46:361416瀏覽

1.瀏覽器請求動態頁面程序

2.WSGI

Python Web Server Gateway Interface (或簡稱WSGI,讀作“wizgy” )。

WSGI允許開發者將選擇web框架和web伺服器分開。可以混合匹配web伺服器和web框架,選擇一個適合的配對。例如,可以在Gunicorn 或 Nginx/uWSGI 或 Waitress上運行 Django, Flask, 或 Pyramid。真正的混合匹配,得益於WSGI同時支援伺服器和架構.

web伺服器必須具備WSGI接口,所有的現代Python Web框架都已具備WSGI接口,它讓你不對代碼作修改就能使伺服器和特點的web框架協同工作。

WSGI由網頁伺服器支持,而web框架允許你選擇適合自己的配對,但它同樣對於伺服器和框架開發者提供便利使他們可以專注於自己偏愛的領域和專長而不至於相互牽制。其他語言也有類似介面:java有Servlet API,Ruby 有 Rack。

3.定義WSGI介面

WSGI介面定義非常簡單,它只要求Web開發者實作一個函數,就可以回應HTTP請求。讓我們來看一個最簡單的Web版本的「Hello World!」:

def application(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/html')])return 'Hello World!'

上面的 application( ) 函數就是符合WSGI標準的一個HTTP處理函數,它接收兩個參數:

  • environ:一個包含所有HTTP請求資訊的dict物件;

  • #start_response:一個傳送HTTP回應的函式。

整個application( )函數本身沒有涉及到任何解析HTTP的部分,也就是說,把底層web伺服器解析部分和應用程式邏輯部分進行了分離,這樣開發者就可以專心做一個領域了.

application( )函數必須由WSGI伺服器來呼叫。有很多符合WSGI規範的伺服器。而我們此時的web伺服器專案的目的就是要做一個極可能解析靜態網頁也可以解析動態網頁的伺服器

實作程式碼:

import time,multiprocessing,socket,os,reclass MyHttpServer(object):def __init__(self):
        serveSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.serveSocket = serveSocket
        self.HTMLPATH = './html'def bind(self,port=8000):
        self.serveSocket.bind(('',port))def start(self):
        self.serveSocket.listen()while True:
            clientSocket, clientAddr = self.serveSocket.accept()
            print(clientSocket)
            multiprocessing.Process(target=self.serveHandler, args=(clientSocket, clientAddr)).start()
            clientSocket.close()def serveHandler(self,clientSocket,clientAddr):try:
            recvData = clientSocket.recv(1024).decode('gbk')
            fileName = re.split(r' +', recvData.splitlines()[0])[1]
            filePath = self.HTMLPATHif fileName.endswith('.py'):try:
                    pyname=fileName[1:-3]# 导入
                    pyModule = __import__(pyname)

                    env={}
                    responseBody = pyModule.application(env,self.startResponse)
                    responseLine = self.responseLine
                    responseHeader = self.responseHeaderexcept ImportError:
                    responseLine = 'HTTP/1.1 404 NOT FOUND'
                    responseHeader = 'Server: ererbai' + os.linesep
                    responseHeader += 'Date: %s' % time.ctime()
                    responseBody = &#39;<h1>很抱歉,服务器中找不到你想要的内容<h1>&#39;else:if &#39;/&#39;== fileName:
                    filePath += &#39;/index.html&#39;else:
                    filePath += fileNametry:
                    file = None
                    file =open(filePath,&#39;r&#39;,encoding=&#39;gbk&#39;)
                    responseBody = file.read()

                    responseLine = &#39;HTTP/1.1 200 OK&#39;
                    responseHeader = &#39;Server: ererbai&#39; + os.linesep
                    responseHeader += &#39;Date:%s&#39; % time.ctime()except FileNotFoundError:
                    responseLine = &#39;HTTP/1.1 404 NOT FOUND&#39;
                    responseHeader = &#39;Server: ererbai&#39; + os.linesep
                    responseHeader += &#39;Date:%s&#39; % time.ctime()
                    responseBody = &#39;很抱歉,服务器中找不到你想要的内容&#39;finally:if (file!=None) and (not file.closed):
                        file.close()except Exception as ex:
            responseLine = &#39;HTTP/1.1 500 ERROR&#39;
            responseHeader = &#39;Server: ererbai&#39; + os.linesep
            responseHeader += &#39;Date: %s&#39; % time.ctime()
            responseBody = &#39;服务器正在维护中,请稍后再试。%s&#39;%exfinally:
            senData = responseLine + os.linesep + responseHeader + os.linesep + os.linesep + responseBody
            print(senData)
            senData = senData.encode(&#39;gbk&#39;)
            clientSocket.send(senData)if (clientSocket!=None) and ( not clientSocket._closed):
                clientSocket.close()def startResponse(self,status,responseHeaders):
        self.responseLine = status
        self.responseHeader = &#39;&#39;for k,v in responseHeaders:
            kv = k + &#39;:&#39; + v + os.linesep
            self.responseHeader += kvif __name__ == &#39;__main__&#39;:
    server = MyHttpServer()
    server.bind(8000)
    server.start()

伺服器中存在的html的檔案:

  • index.html

<html><head><title>首页-毕业季</title><meta http-equiv=Content-Type content="text/html;charset=gbk"></head><body>我们仍需共生命的慷慨与繁华相爱,即使岁月以刻薄和荒芜相欺。</body></html>
  • #biye.html

  • ##
    <!DOCTYPE html><html lang="en"><head><meta charset="gbk"><title>毕业季</title></head><body>![](http://localhost:51017/day18/html/biyeji.png)<br>当年以为六月不过也很平常<br>当自己真正经历了毕业<br>才知道偶尔看到六月毕业季等字里所流露的种种想要重温却不敢提及的回忆<br>毕业了<br>那个夏天,我的毕业季,我的青春年少<br>六月<br>有人笑着说解脱,有人哭着说不舍<br>那年,<br>你对我说的你好<br>在不知不觉中<br>变成了<br>再见。</body></html>

biyeji.png
mytime.py檔案

import timedef application(env,startResponse):
    status = &#39;HTTP/1.1 200 OK&#39;
    responseHeaders = [(&#39;Server&#39;,&#39;bfe/1.0.8.18&#39;),(&#39;Date&#39;,&#39;%s&#39;%time.ctime()),(&#39;Content-Type&#39;,&#39;text/plain&#39;)]
    startResponse(status,responseHeaders)

    responseBody = str(time.ctime())return responseBody

存取結果:

##首頁
biye.html
#mytime.py
&#39;&#39;&#39;
自定义的符合wsgi的框架
&#39;&#39;&#39;import timeclass Application(object):def __init__(self, urls):&#39;&#39;&#39;框架初始化的时候需要获取路由列表&#39;&#39;&#39;
        self.urls = urlsdef __call__(self, env, startResponse):&#39;&#39;&#39;
        判断是静态资源还是动态资源。
        设置状态码和响应头和响应体
        :param env:
        :param startResponse:
        :return:
        &#39;&#39;&#39;# 从请求头中获取文件名
        fileName = env.get(&#39;PATH_INFO&#39;)# 判断静态还是动态if fileName.startwith(&#39;/static&#39;):
            fileName = fileName[7:]if &#39;/&#39; == fileName:
                filePath += &#39;/index.html&#39;else:
                filePath += fileNametry:
                file = None
                file = open(filePath, &#39;r&#39;, encoding=&#39;gbk&#39;)
                responseBody = file.read()
                status = &#39;HTTP/1.1 200 OK&#39;
                responseHeaders = [(&#39;Server&#39;, &#39;ererbai&#39;)]except FileNotFoundError:
                status = &#39;HTTP/1.1 404 Not Found&#39;
                responseHeaders = [(&#39;Server&#39;, &#39;ererbai&#39;)]
                responseBody = &#39;<h1>找不到<h1>&#39;finally:
                startResponse(status, responseHeaders)if (file != None) and (not file.closed):
                    file.close()else:
            isHas = False  # 表示请求的名字是否在urls中,True:存在,False:不存在for url, func in self.urls:if url == fileName:
                    responseBody = func(env, startResponse)
                    isHas = Truebreakif isHas == False:
                status = &#39;HTTP/1.1 404 Not Found&#39;
                responseHeaders = [(&#39;Server&#39;, &#39;ererbai&#39;)]
                responseBody = &#39;<h1>找不到<h1>&#39;
                startResponse(status, responseHeaders)return responseBodydef mytime(env, startResponse):
    status = &#39;HTTP/1.1 200 OK&#39;
    responseHeaders = [(&#39;Server&#39;, &#39;time&#39;)]
    startResponse(status, responseHeaders)
    responseBody = str(time.ctime())return responseBodydef mynews(env, startResponse):
    status = &#39;HTTP/1.1 200 OK&#39;
    responseHeaders = [(&#39;Server&#39;, &#39;news&#39;)]
    startResponse(status, responseHeaders)
    responseBody = str(&#39;xx新闻&#39;)return responseBody&#39;&#39;&#39;路由列表&#39;&#39;&#39;
urls = [
    (&#39;/mytime&#39;, mytime),
    (&#39;/mynews&#39;, mynews)
]

application = Application(urls)
學習過程中遇到什麼問題或想獲取學習資源的話,歡迎加入學習交流群
626062078,我們一起學Python!

以上是Python的web伺服器相關知識點的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn