日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

自定义Web框架

發(fā)布時(shí)間:2023/12/15 综合教程 34 生活家
生活随笔 收集整理的這篇文章主要介紹了 自定义Web框架 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

自定義Web框架

http協(xié)議

HTTP簡介

HTTP協(xié)議是Hyper Text Transfer Protocol(超文本傳輸協(xié)議)的縮寫,是用于從萬維網(wǎng)(WWW:World Wide Web )服務(wù)器傳輸超文本到本地瀏覽器的傳送協(xié)議。

HTTP是一個(gè)基于TCP/IP通信協(xié)議來傳遞數(shù)據(jù)(HTML 文件, 圖片文件, 查詢結(jié)果等)。

HTTP是一個(gè)屬于應(yīng)用層的面向?qū)ο蟮膮f(xié)議,由于其簡捷、快速的方式,適用于分布式超媒體信息系統(tǒng)。它于1990年提出,經(jīng)過幾年的使用與發(fā)展,得到不斷地完善和擴(kuò)展。目前在WWW中使用的是HTTP/1.0的第六版,HTTP/1.1的規(guī)范化工作正在進(jìn)行之中,而且HTTP-NG(Next Generation of HTTP)的建議已經(jīng)提出。

HTTP協(xié)議工作于客戶端-服務(wù)端架構(gòu)為上。瀏覽器作為HTTP客戶端通過URL向HTTP服務(wù)端即WEB服務(wù)器發(fā)送所有請(qǐng)求。Web服務(wù)器根據(jù)接收到的請(qǐng)求后,向客戶端發(fā)送響應(yīng)信息。

HTTP特點(diǎn)

1、簡單快速:客戶向服務(wù)器請(qǐng)求服務(wù)時(shí),只需傳送請(qǐng)求方法和路徑。請(qǐng)求方法常用的有GET、HEAD、POST。每種方法規(guī)定了客戶與服務(wù)器聯(lián)系的類型不同。由于HTTP協(xié)議簡單,使得HTTP服務(wù)器的程序規(guī)模小,因而通信速度很快。

2、靈活:HTTP允許傳輸任意類型的數(shù)據(jù)對(duì)象。正在傳輸?shù)念愋陀蒀ontent-Type加以標(biāo)記。

3.無連接:無連接的含義是限制每次連接只處理一個(gè)請(qǐng)求。服務(wù)器處理完客戶的請(qǐng)求,并收到客戶的應(yīng)答后,即斷開連接。采用這種方式可以節(jié)省傳輸時(shí)間。

4.無狀態(tài):HTTP協(xié)議是無狀態(tài)協(xié)議。無狀態(tài)是指協(xié)議對(duì)于事務(wù)處理沒有記憶能力。缺少狀態(tài)意味著如果后續(xù)處理需要前面的信息,則它必須重傳,這樣可能導(dǎo)致每次連接傳送的數(shù)據(jù)量增大。另一方面,在服務(wù)器不需要先前信息時(shí)它的應(yīng)答就較快。

HTTP請(qǐng)求協(xié)議

請(qǐng)求協(xié)議遵照以下格式:

請(qǐng)求首行;        // 請(qǐng)求方式 請(qǐng)求路徑 協(xié)議和版本,例如:GET /index.html HTTP/1.1
請(qǐng)求頭信息;      // 請(qǐng)求頭名稱:請(qǐng)求頭內(nèi)容,即為key:value格式,例如:Host:localhost
空行;           // 用來與請(qǐng)求體分隔開
請(qǐng)求體。         // GET沒有請(qǐng)求體,只有POST有請(qǐng)求體。

瀏覽器發(fā)送給服務(wù)器的內(nèi)容就這個(gè)格式的,如果不是這個(gè)格式服務(wù)器將無法解讀!在HTTP協(xié)議中,請(qǐng)求有很多請(qǐng)求方法,其中最為常用的就是GET和POST。

get請(qǐng)求


GET /562f25980001b1b106000338.jpg HTTP/1.1
Host    img.mukewang.com
User-Agent    Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36
Accept    image/webp,image/*,*/*;q=0.8
Referer    http://www.imooc.com/
Accept-Encoding    gzip, deflate, sdch
Accept-Language    zh-CN,zh;q=0.8


HTTP默認(rèn)的請(qǐng)求方法就是GET
* 沒有請(qǐng)求體
* 數(shù)據(jù)量有限制!
* GET請(qǐng)求數(shù)據(jù)會(huì)暴露在瀏覽器的地址欄中

GET請(qǐng)求常用的操作:
1. 在瀏覽器的地址欄中直接給出URL,那么就一定是GET請(qǐng)求
2. 點(diǎn)擊頁面上的超鏈接也一定是GET請(qǐng)求
3. 提交表單時(shí),表單默認(rèn)使用GET請(qǐng)求,但可以設(shè)置為POST

請(qǐng)求頭:


1、Host

請(qǐng)求的web服務(wù)器域名地址

2、User-Agent

HTTP客戶端運(yùn)行的瀏覽器類型的詳細(xì)信息。通過該頭部信息,web服務(wù)器可以判斷出http請(qǐng)求的客戶端的瀏覽器的類型。

3、Accept

指定客戶端能夠接收的內(nèi)容類型,內(nèi)容類型的先后次序表示客戶都接收的先后次序

4、Accept-Lanuage

指定HTTP客戶端瀏覽器用來展示返回信息優(yōu)先選擇的語言

5、Accept-Encoding

指定客戶端瀏覽器可以支持的web服務(wù)器返回內(nèi)容壓縮編碼類型。表示允許服務(wù)器在將輸出內(nèi)容發(fā)送到客戶端以前進(jìn)行壓縮,以節(jié)約帶寬。
而這里設(shè)置的就是客戶端瀏覽器所能夠支持的返回壓縮格式。 6、Accept-Charset HTTP客戶端瀏覽器可以接受的字符編碼集 7、Content-Type 顯示此HTTP請(qǐng)求提交的內(nèi)容類型。一般只有post提交時(shí)才需要設(shè)置該屬性 有關(guān)Content-Type屬性值有如下兩種編碼類型: (1)“application/x-www-form-urlencoded”: 表單數(shù)據(jù)向服務(wù)器提交時(shí)所采用的編碼類型,默認(rèn)的缺省值就是“application/x-www-form-urlencoded”。
然而,在向服務(wù)器發(fā)送大量的文本、包含非ASCII字符的文本或二進(jìn)制數(shù)據(jù)時(shí)這種編碼方式效率很低。 (2)“multipart/form-data”: 在文件上載時(shí),所使用的編碼類型應(yīng)當(dāng)是“multipart/form-data”,它既可以發(fā)送文本數(shù)據(jù),也支持二進(jìn)制數(shù)據(jù)上載。 當(dāng)提交為表單數(shù)據(jù)時(shí),可以使用“application/x-www-form-urlencoded”;當(dāng)提交的是文件時(shí),就需要使用“multipart/form-data”編碼類型。 8、Keep-Alive 表示是否需要持久連接。如果web服務(wù)器端看到這里的值為“Keep-Alive”,或者看到請(qǐng)求使用的是HTTP 1.1(HTTP 1.1默認(rèn)進(jìn)行持久連接),它就可以利用持久連接的優(yōu)點(diǎn)


post請(qǐng)求


POST / HTTP1.1
Host:www.wrox.com
User-Agent:Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)
Content-Type:application/x-www-form-urlencoded
Content-Length:40
Connection: Keep-Alive

name=Professional%20Ajax&publisher=Wiley


第一部分:請(qǐng)求行,第一行明了是post請(qǐng)求,以及http1.1版本。
第二部分:請(qǐng)求頭部,第二行至第六行。
第三部分:空行,第七行的空行。
第四部分:請(qǐng)求數(shù)據(jù),第八行。

HTTP響應(yīng)協(xié)議

響應(yīng)格式

一般情況下,服務(wù)器接收并處理客戶端發(fā)過來的請(qǐng)求后會(huì)返回一個(gè)HTTP的響應(yīng)消息。

HTTP響應(yīng)也由四個(gè)部分組成,分別是:狀態(tài)行、消息報(bào)頭、空行和響應(yīng)正文。

http響應(yīng)消息格式.jpg

例子



HTTP/1.1 200 OK
Date: Fri, 22 May 2009 06:07:21 GMT
Content-Type: text/html; charset=UTF-8

<html>
      <head></head>
      <body>
            <!--body goes here-->
      </body>
</html>


第一部分:狀態(tài)行,由HTTP協(xié)議版本號(hào), 狀態(tài)碼, 狀態(tài)消息 三部分組成。

第一行為狀態(tài)行,(HTTP/1.1)表明HTTP版本為1.1版本,狀態(tài)碼為200,狀態(tài)消息為(ok)

第二部分:消息報(bào)頭,用來說明客戶端要使用的一些附加信息

第二行和第三行為消息報(bào)頭,
Date:生成響應(yīng)的日期和時(shí)間;Content-Type:指定了MIME類型的HTML(text/html),編碼類型是UTF-8

第三部分:空行,消息報(bào)頭后面的空行是必須的
第四部分:響應(yīng)正文,服務(wù)器返回給客戶端的文本信息。

空行后面的html部分為響應(yīng)正文。

響應(yīng)狀態(tài)碼


狀態(tài)代碼有三位數(shù)字組成,第一個(gè)數(shù)字定義了響應(yīng)的類別,共分五種類別:
1xx:指示信息--表示請(qǐng)求已接收,繼續(xù)處理
2xx:成功--表示請(qǐng)求已被成功接收、理解、接受
3xx:重定向--要完成請(qǐng)求必須進(jìn)行更進(jìn)一步的操作
4xx:客戶端錯(cuò)誤--請(qǐng)求有語法錯(cuò)誤或請(qǐng)求無法實(shí)現(xiàn)
5xx:服務(wù)器端錯(cuò)誤--服務(wù)器未能實(shí)現(xiàn)合法的請(qǐng)求

常見狀態(tài)碼:

200 OK                        //客戶端請(qǐng)求成功
400 Bad Request               //客戶端請(qǐng)求有語法錯(cuò)誤,不能被服務(wù)器所理解
401 Unauthorized              //請(qǐng)求未經(jīng)授權(quán),這個(gè)狀態(tài)代碼必須和WWW-Authenticate報(bào)頭域一起使用 
403 Forbidden                 //服務(wù)器收到請(qǐng)求,但是拒絕提供服務(wù)
404 Not Found                 //請(qǐng)求資源不存在,eg:輸入了錯(cuò)誤的URL
500 Internal Server Error     //服務(wù)器發(fā)生不可預(yù)期的錯(cuò)誤
503 Server Unavailable        //服務(wù)器當(dāng)前不能處理客戶端的請(qǐng)求,一段時(shí)間后可能恢復(fù)正常


GET和POST請(qǐng)求的區(qū)別


GET請(qǐng)求

GET /books/?sex=man&name=Professional HTTP/1.1
Host: www.wrox.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6)
Gecko/20050225 Firefox/1.0.1
Connection: Keep-Alive

注意最后一行是空行
POST請(qǐng)求

POST / HTTP/1.1
Host: www.wrox.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6)
Gecko/20050225 Firefox/1.0.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 40
Connection: Keep-Alive

name=Professional%20Ajax&publisher=Wiley


1、GET提交,請(qǐng)求的數(shù)據(jù)會(huì)附在URL之后(就是把數(shù)據(jù)放置在HTTP協(xié)議頭中),以?分割URL和傳輸數(shù)據(jù),多個(gè)參數(shù)用&連接;例 如:login.action?name=hyddd&password=idontknow&verify=%E4%BD%A0 %E5%A5%BD。如果數(shù)據(jù)是英文字母/數(shù)字,原樣發(fā)送,如果是空格,轉(zhuǎn)換為+,如果是中文/其他字符,則直接把字符串用BASE64加密,得出如: %E4%BD%A0%E5%A5%BD,其中%XX中的XX為該符號(hào)以16進(jìn)制表示的ASCII。

POST提交:把提交的數(shù)據(jù)放置在是HTTP包的包體中。上文示例中紅色字體標(biāo)明的就是實(shí)際的傳輸數(shù)據(jù)

因此,GET提交的數(shù)據(jù)會(huì)在地址欄中顯示出來,而POST提交,地址欄不會(huì)改變

2、傳輸數(shù)據(jù)的大小:首先聲明:HTTP協(xié)議沒有對(duì)傳輸?shù)臄?shù)據(jù)大小進(jìn)行限制,HTTP協(xié)議規(guī)范也沒有對(duì)URL長度進(jìn)行限制。

而在實(shí)際開發(fā)中存在的限制主要有:

GET:特定瀏覽器和服務(wù)器對(duì)URL長度有限制,例如 IE對(duì)URL長度的限制是2083字節(jié)(2K+35)。對(duì)于其他瀏覽器,如Netscape、FireFox等,理論上沒有長度限制,其限制取決于操作系 統(tǒng)的支持。

因此對(duì)于GET提交時(shí),傳輸數(shù)據(jù)就會(huì)受到URL長度的 限制。

POST:由于不是通過URL傳值,理論上數(shù)據(jù)不受 限。但實(shí)際各個(gè)WEB服務(wù)器會(huì)規(guī)定對(duì)post提交數(shù)據(jù)大小進(jìn)行限制,Apache、IIS6都有各自的配置。

GET和POST的區(qū)別

GET提交的數(shù)據(jù)會(huì)放在URL之后,以?分割URL和傳輸數(shù)據(jù),參數(shù)之間以&相連,如EditPosts.aspx?name=test1&id=123456. POST方法是把提交的數(shù)據(jù)放在HTTP包的Body中.

GET提交的數(shù)據(jù)大小有限制(因?yàn)闉g覽器對(duì)URL的長度有限制),而POST方法提交的數(shù)據(jù)沒有限制.

GET方式需要使用Request.QueryString來取得變量的值,而POST方式通過Request.Form來獲取變量的值。

GET方式提交數(shù)據(jù),會(huì)帶來安全問題,比如一個(gè)登錄頁面,通過GET方式提交數(shù)據(jù)時(shí),用戶名和密碼將出現(xiàn)在URL上,如果頁面可以被緩存或者其他人可以訪問這臺(tái)機(jī)器,就可以從歷史記錄獲得該用戶的賬號(hào)和密碼.

web應(yīng)用與web框架

web應(yīng)用

對(duì)于所有的Web應(yīng)用,本質(zhì)上其實(shí)就是一個(gè)socket服務(wù)端,用戶的瀏覽器其實(shí)就是一個(gè)socket客戶端。


import socket

def handle_request(client):

    buf = client.recv(1024)
    client.send("HTTP/1.1 200 OK

".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應(yīng)用就是先把HTML用文件保存好,用一個(gè)現(xiàn)成的HTTP服務(wù)器軟件,接收用戶請(qǐng)求,從文件中讀取HTML,返回。

如果要?jiǎng)討B(tài)生成HTML,就需要把上述步驟自己來實(shí)現(xiàn)。不過,接受HTTP請(qǐng)求、解析HTTP請(qǐng)求、發(fā)送HTTP響應(yīng)都是苦力活,如果我們自己來寫這些底層代碼,還沒開始寫動(dòng)態(tài)HTML呢,就得花個(gè)把月去讀HTTP規(guī)范。

正確的做法是底層代碼由專門的服務(wù)器軟件實(shí)現(xiàn),我們用Python專注于生成HTML文檔。因?yàn)槲覀儾幌M佑|到TCP連接、HTTP原始請(qǐng)求和響應(yīng)格式,所以,需要一個(gè)統(tǒng)一的接口,讓我們專心用Python編寫Web業(yè)務(wù)。

這個(gè)接口就是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...')
# 開始監(jiān)聽HTTP請(qǐng)求:
httpd.serve_forever()


DIY一個(gè)自己的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()


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)


        #當(dāng)請(qǐng)求方式是GET時(shí)
        # user_union,pwd_union=request.get("QUERY_STRING").split("&")
        # _,user=user_union.split("=")
        # _,pwd=pwd_union.split("=")

        # 環(huán)境變量 CONTENT_LENGTH 可能是空值 或者 值丟失
        try:
            request_body_size = int(request.get('CONTENT_LENGTH', 0))
        except (ValueError):
            request_body_size = 0
        # 當(dāng)請(qǐng)求方式是POST時(shí), 變量將會(huì)被放在存在域wsgi.input文件中的HTTP請(qǐng)求信息中, 由WSGI 服務(wù)器一起發(fā)送.
        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)


        #連接數(shù)據(jù)庫
        conn = pymysql.connect(host='',port= 3306,user = 'root',passwd='',db='s6') #db:庫名
        #創(chuàng)建游標(biāo)
        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 data


models


import pymysql


import pymysql
#連接數(shù)據(jù)庫
conn = pymysql.connect(host='',port= 3306,user = 'root',passwd='',db='s6') #db:庫名
#創(chuàng)建游標(biāo)
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()
#關(guān)閉指針對(duì)象
cur.close()
#關(guān)閉連接對(duì)象
conn.close()


總結(jié)

以上是生活随笔為你收集整理的自定义Web框架的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。