web應用與web框架(Day65)
阿新 • • 發佈:2017-10-23
pos ack ++ 環境 lex roo http請求 main conn
Web應用
對於所有的web應用,本質上其實就是一個socket服務端,用戶的瀏覽器其實就是一個socket客戶端
import socket def handle_request(client): buf = client.recv(1024) client.send("HTTP/1.1 200 OK\r\n\r\n".encode("utf8")) client.send("<h1 style=‘color:red‘>Hello, yuan</h1>".encode("utf8")) def main(): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.bind((‘localhost‘,8001)) sock.listen(5) while True: connection, address = sock.accept() handle_request(connection) connection.close() if __name__ == ‘__main__‘: main()
最簡單的web應用就是先把HTML用文件保存好,用一個現成的HTTP服務器軟件,接受用戶請求,接受用戶請求並返回
如果要動態生成HTML,就需要把上述步驟自己來實現。不過,接受HTTP請求、解析HTTP請求、發送HTTP響應都是苦力活,如果我們自己來寫這些底層代碼,還沒開始寫動態HTML呢,就得花個把月去讀HTTP規範。
正確的做法是底層代碼由專門的服務器軟件實現,我們用Python專註於生成HTML文檔。因為我們不希望接觸到TCP連接、HTTP原始請求和響應格式,所以,需要一個統一的接口,讓我們專心用Python編寫Web業務。
這個接口就是WSGI:Web Server Gateway Interface。
wsgiref模塊
from wsgiref.simple_server import make_server def application(environ, start_response): start_response(‘200 OK‘, [(‘Content-Type‘, ‘text/html‘)]) return [b‘<h1>Hello, web!</h1>‘] httpd = make_server(‘‘, 8080, application) print(‘Serving HTTP on port 8000...‘) # 開始監聽HTTP請求: httpd.serve_forever()
對比socketserver模塊
DIY一個自己的web框架
manage.py
from wsgiref.simple_server import make_server # request response from app01.views import * from app01 import urls def routers(): URLpattern=urls.URLpattern return URLpattern def applications(environ,start_response): path=environ.get("PATH_INFO") print("path",path) start_response(‘200 OK‘, [(‘Content-Type‘, ‘text/html‘),(‘Charset‘, ‘utf8‘)]) urlpattern=routers() func=None for item in urlpattern: if path==item[0]: func=item[1] break if func: return [func(environ)] else: return [b"<h1>404!<h1>"] # return [b"<h1>hello world<h1>"] if __name__ == ‘__main__‘: t=make_server("",8810,applications) print("server is working...") t.serve_forever()View Code
urls
from app01.views import * URLpattern = ( ("/login/", login), )
views
import pymysql from urllib.parse import parse_qs def login(request): if request.get("REQUEST_METHOD")=="POST": print("+++++",request) #當請求方式是GET時 # user_union,pwd_union=request.get("QUERY_STRING").split("&") # _,user=user_union.split("=") # _,pwd=pwd_union.split("=") # 環境變量 CONTENT_LENGTH 可能是空值 或者 值丟失 try: request_body_size = int(request.get(‘CONTENT_LENGTH‘, 0)) except (ValueError): request_body_size = 0 # 當請求方式是POST時, 變量將會被放在存在域wsgi.input文件中的HTTP請求信息中, 由WSGI 服務器一起發送. request_body = request[‘wsgi.input‘].read(request_body_size) d = parse_qs(request_body) user=d.get(b"user")[0].decode("utf8") pwd=d.get(b"pwd")[0].decode("utf8") print("user",user,pwd) #連接數據庫 conn = pymysql.connect(host=‘‘,port= 3306,user = ‘root‘,passwd=‘‘,db=‘s6‘) #db:庫名 #創建遊標 cur = conn.cursor() SQL="select * from userinfo2 WHERE NAME =‘%s‘ AND PASSWORD =‘%s‘"%(user,pwd) cur.execute(SQL) if cur.fetchone(): f=open("templates/backend.html","rb") data=f.read() data=(data.decode("utf8"))%user return data.encode("utf8") else: return b"user or pwd is wrong" else: f = open("templates/login.html", "rb") data = f.read() f.close() return dataView Code
models
import pymysql import pymysql #連接數據庫 conn = pymysql.connect(host=‘‘,port= 3306,user = ‘root‘,passwd=‘‘,db=‘s6‘) #db:庫名 #創建遊標 cur = conn.cursor() # sql=‘‘‘ # create table userinfo2( # id INT PRIMARY KEY , # name VARCHAR(32) , # password VARCHAR(32) # ) # # ‘‘‘ # # cur.execute(sql) # # cur.executemany("insert into userinfo2 values(%s,%s,%s)", [(1,"yuan","123"), # (2,"alex","456"), # (3,"egon","789")]) cur.execute("select * from userinfo2 WHERE NAME=‘yuan‘ AND PASSWORD =‘123‘") #提交 conn.commit() #關閉指針對象 cur.close() #關閉連接對象 conn.close()View Code
web應用與web框架(Day65)