[] DjangoのWebフレームワークの本質

@
*
我々はそれをこのように解釈することができます。すべての== Webアプリケーションは、基本的にソケットサーバー==で、ユーザーのブラウザはソケット==終了==顧客サービスです。**

私たちは、独自のWebフレームワークを実装することが可能に:

from socket import *

sk = socket(AF_INET, SOCK_STREAM)
sk.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
sk.bind(('127.0.0.1', 8080))
sk.listen()

while True:
    conn, addr = sk.accept()
    data = conn.recv(9000)
    conn.send(b'HTTP/1.1 200 OK\r\n\r\n')       # 响应状态行
    conn.send(b'Hello,world!')
    conn.close()

これは、Webサービス拡張にこのコードは、自分の父親である、コードベースのこのダースラインのうち、本質的にあると言うことができます。

ユーザーのブラウザは、URLを入力すると、サーバーは、ブラウザがどのようなデータを送信します、そのデータを送信しますか?どのように髪?誰がこれを固定しましたか?あなたのウェブサイトは、彼がその条項、インターネットはそれを再生することができたという彼のWebサイトによると、この条項のですか?
我々だけではなく、書くこと、メッセージを送信する形式の根拠がある場合に、メッセージを受け取ることができるように、そのため、均一なルールが存在しなければなりません。
このルールは、HTTPプロトコルであり、ブラウザがイェジンハオ後に要求メッセージを送信し、サーバは言及する価値が応答情報を返信、この規則に従ってください。
クライアントとサーバ間のHTTPプロトコルの通信フォーマットの主な条項、メッセージ形式がそれを規定する方法であるHTTPプロトコル?

私たちがしているサービス終了で受信したメッセージ何を最初に印刷してみましょう:

from socket import *

sk = socket(AF_INET, SOCK_STREAM)
sk.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
sk.bind(('127.0.0.1', 8080))
sk.listen()

while True:
    conn, addr = sk.accept()
    data = conn.recv(9000)
    print(data)  # 将浏览器发来的消息打印出来
    conn.send(b'HTTP/1.1 200 OK\r\n\r\n')
    conn.send(b'Hello,world!')
    conn.close()

次のように出力されます。

b'GET / HTTP / 1.1 \ rを\ nHost:127.0.0.1:8080\r\nConnection:キープアライブ\ rを\ nPragma:キャッシュなし\ rを\のnCache-コントロール:キャッシュなし\ rを\ nUpgrade-Insecure-要求:1 \ rを\ nユーザーエージェント:Mozillaの/ 5.0(Macintosh版、インテルのMac OS X 10_13_6)のAppleWebKit / 537.36(KHTML、ヤモリなど)クローム/ 68.0.3440.106サファリ/ 537.36 \ rを\ nAccept:text / htmlで、アプリケーション/ XHTML + xmlの、アプリケーション/ XML、Q = 0.9、画像/ WEBP、画像/ APNG、/ ; Q = 0.8 \ R \ nAcceptエンコーディング:gzipで、収縮、BR \ R \ nAccept言語:ZH-CN、ZH。 Q = 0.9、EN; Q = 0.8 \ R \のn個の\ r \ n」

その後、我々は、応答に関する情報は、ネットワークブラウザタブデバッグウィンドウで見ることができ、私たちが受けているもののブログ公式Webブラウザへのアクセス情報に応答が表示されます。
ここに画像を挿入説明
私たちは、特定のフォーマットに従って送信され、受信したメッセージを見つける必要があり、ここでは、HTTPプロトコルを知ることが必要です。

ボディはオプションである各HTTP要求と応答は、2つの部分を含む同じフォーマット、HTTPヘッダとボディをたどります。ヘッダーHTTP応答は、応答の==のContent-Typeの==ショーのコンテンツフォーマットを持っています。== text / htmlのよう== HTMLページを表しています。

HTTP GETリクエストのフォーマット:
ここに画像を挿入説明

HTTPレスポンス形式:
ここに画像を挿入説明
****

パスに応じて異なるコンテンツを返します。

==アイデア:要求データ、そこから経路要求URLを取得し、==パスを取る判断をします。

from socket import *

sk = socket(AF_INET, SOCK_STREAM)
sk.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
sk.bind(('127.0.0.1', 8080))
sk.listen()

while True:
    conn, addr = sk.accept()
    data = conn.recv(8096)
    # 把收到的字节类型的数据转换成字符串
    data_str = str(data, encoding='UTF-8')
    first_line = data_str.split('\r\n')[0]  # 按\r\n分隔
    url = first_line.split()[1]  # 在按空格切割
    conn.send(b'HTTP/1.1 200 OK\r\n\r\n')  # 响应状态行

    if url == '/index':
        response = 'index'
    elif url == '/home':
        response = 'home'
    else:
        response = '404 not found!'

    conn.send(bytes(response, encoding='UTF-8'))
    conn.close()

解き上記のコードは異なるURLパスの要件ごとに異なるコンテンツを返します。
しかし、再び問題、それを行う方法を決定するために多くのパスがある場合は?あなたは裁判官ならば一つ一つを書いてみませんか?
答えはノー、我々はより巧妙な方法を持っています:

機能バージョン

from socket import *

sk = socket(AF_INET, SOCK_STREAM)
sk.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
sk.bind(('127.0.0.1', 8080))
sk.listen()


# 将返回不同的内容部分封装成函数
def index(url):
    s = "这是%s页面!" % url
    return bytes(s, encoding='UTF-8')


def home(url):
    s = "这是%s页面!" % url
    return bytes(s, encoding='UTF-8')


while True:
    conn, addr = sk.accept()
    data = conn.recv(8096)
    # 把收到的字节类型的数据转换成字符串
    data_str = str(data, encoding='UTF-8')
    first_line = data_str.split('\r\n')[0]  # 按\r\n分隔
    url = first_line.split()[1]  # 在按空格切割
    conn.send(b'HTTP/1.1 200 OK\r\n\r\n')  # 响应状态行

    if url == '/index':
        response = index(url)
    elif url == '/home':
        response = home(url)
    else:
        response = b'404 not found!'

    conn.send(response)
    conn.close()

上記のコードは見えますか、どのように行う場合は、1つずつを決定するために書くこと?
限りイデオロギーが地すべりではないとして、この方法は、歩いて、より多くの問題よりも優れています!

プレミアム機能

from socket import *

sk = socket(AF_INET, SOCK_STREAM)
sk.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
sk.bind(('127.0.0.1', 8080))
sk.listen()


# 将返回不同的内容部分封装成函数
def index(url):
    s = "这是%s页面!" % url
    return bytes(s, encoding='UTF-8')


def home(url):
    s = "这是%s页面!" % url
    return bytes(s, encoding='UTF-8')


# 定义一个url和实际要执行的函数的对应关系
url_list = [
    ('/index', index),
    ('/home', home)
]

while True:
    conn, addr = sk.accept()
    data = conn.recv(8096)
    # 把收到的字节类型的数据转换成字符串
    data_str = ?tr(data, encoding='UTF-8')
    first_line = data_str.split('\r\n')[0]  # 按\r\n分隔
    url = first_line.split()[1]  # 在按空格切割
    conn.send(b'HTTP/1.1 200 OK\r\n\r\n')  # 响应状态行


    # -------关键就在于这一坨代码-------
    func = None
    for i in url_list:
        if url == i[0]:
            func = i[1]
            break
    response = func(url) if func else b'404 not found!'


    conn.send(response)
    conn.close()

異なるコンテンツの問題を返すために完璧なソリューション異なるURL。
しかし、我々は単に複数の文字列を返すようにしたい、私たちはこれを行うべきか、ブラウザは完全なHTMLコンテンツを返す与えたいと思いますか?そして、行きます!
***

特定のHTMLファイルを返します。

まず、私たちが知っている必要があり、すべての:。==何があって、データの最後のバイトを==に変換されていない送り出さ
そこで、我々は、バイナリ形式でHTMLファイルを開き、データファイルを読み込み、その後、ブラウザに送信することができます。

from socket import *

sk = socket(AF_INET, SOCK_STREAM)
sk.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
sk.bind(('127.0.0.1', 8080))
sk.listen()


# 将返回不同的内容部分封装成函数
def index(url):
    with open('index.html', 'rb') as f: return f.read()


def home(url):
    with open('home.html', 'rb') as f: return f.read()


# 定义一个url和实际要执行的函数的对应关系
url_list = [
    ('/index', index),
    ('/home', home)
]

while True:
    # ------------ 建立连接 接收消息 ------------
    conn, addr = sk.accept()
    data = conn.recv(8096)

    # ------------ 对客服端发来的消息做处理 ------------
    # 把收到的字节类型的数据转换成字符串
    data_str = str(data, encoding='UTF-8')
    first_line = data_str.split('\r\n')[0]  # 按\r\n分隔
    url = first_line.split()[1]  # 在按空格切割

    # ------------ 业务逻辑处理部分 ------------
    func = None
    for i in url_list:
        if url == i[0]:
            func = i[1]
            break
    response = func(url) if func else b'404 not found!'

    # ----------- 回复响应消息 -----------
    conn.send(b'HTTP/1.1 200 OK\r\n\r\n')  # 响应状态行
    conn.send(response)
    conn.close()

はい、問題があります!
このページでは、我々は、動的ウェブサイトをしたい、表示することができますが、静的なああです、ページの内容は変更されません!
***

動的なWebページを作ります

==アイデア:この要求を実現するために文字列置換機能を使用して==。
ここでは、動的なデータをシミュレートするために、現在の時刻を使用しています

ログイン機能は、ファイルに対応しています。

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta http-equiv="content-Type" charset="UTF-8">
    <meta http-equiv="x-ua-compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>login</title>
</head>
<body>
<h1>登录页面</h1>
<h1>This is login page!</h1>
<a href="https://blog.csdn.net/qq_41964425/article/category/8083068" target="_blank">CSDN</a>

<p>时间:@@xx@@</p>    <!--提前定义好特殊符号-->
</body>
</html>

Pythonコード:

from time import strftime
from socket import *

sk = socket(AF_INET, SOCK_STREAM)
sk.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
sk.bind(('127.0.0.1', 8080))
sk.listen()


# 将返回不同的内容部分封装成函数
def index(url):
    with open('index.html', 'rb') as f: return f.read()


def home(url):
    with open('home.html', 'rb') as f: return f.read()


# 实现动态网页
def login(url):
    now_time = str(strftime('%F %T'))
    with open('login.html', 'r', encoding='UTF-8') as f:
        s = f.read()
    # 在网页中定义好特殊符号,用动态的数据去替换定义好的特殊符号
    s = s.replace('@@xx@@', now_time)
    return bytes(s, encoding='UTF-8')


# 定义一个url和实际要执行的函数的对应关系
url_list = [
    ('/index', index),
    ('/home', home),
    ('/login', login),
]

while True:
    # ------------ 建立连接 接收消息 ------------
    conn, addr = sk.accept()
    data = conn.recv(8096)

    # ------------ 对客服端发来的消息做处理 ------------
    # 把收到的字节类型的数据转换成字符串
    data_str = str(data, encoding='UTF-8')
    first_line = data_str.split('\r\n')[0]  # 按\r\n分隔
    url = first_line.split()[1]  # 在按空格切割

    # ------------ 业务逻辑处理部分 ------------
    func = None
    for i in url_list:
        if url == i[0]:
            func = i[1]
            break
    response = func(url) if func else b'404 not found!'

    # ----------- 回复响应消息 -----------
    conn.send(b'HTTP/1.1 200 OK\r\n\r\n')  # 响应状态行
    conn.send(response)
    conn.close()

サーバーとアプリケーション

サーバーとアプリケーション== ==:PythonのWeb開発プログラムの場合、一般的には二つの部分に分割されます。

サーバープログラムは、ソケットサーバーをカプセル化するための責任がある、との要求は、様々なデータ要求の照合を到着し、特定のアプリケーション・ロジックを担当しています。

その上ジャンゴ、フラスコ、web.pyと:アプリケーションの開発を容易にするために、のような数多くのWebフレームワークがありました。異なるフレームワークは、開発のさまざまな方法を持っていますが、どのような場合には、開発したアプリケーションとサーバー・プログラムは、ユーザーにサービスを提供するために協働します。

このように、サーバプログラムは、異なるフレームの異なるサポートを提供する必要があります。このような混乱やそれがサーバーフレームワークのためにあるかどうかは、良いものではありません。

このとき、標準化が特に重要になり、私たちは、限り、サーバーがこの標準をサポートしているように、フレームワークはまた、彼らは一緒に使用することができ、この標準をサポートして、標準を設定することができます。標準が決定されると、当事者のそれぞれが実現しています。

WSGI(Webサーバゲートウェイインターフェース)は、仕様です。これは、WebアプリケーションとWebサーバプログラム間のデカップリング、PythonのWebアプリケーションとWebサーバプログラムで記述されたフォーマット間のインタフェースを定義します。

一般的に使用されるWSGIサーバはGunicorn、uwsgiています。wsgirefと呼ばれるWSGIサーバの独立したPythonの標準ライブラリには、== Djangoの開発環境は、サーバーを行うには、このモジュールを使用することである。==

wsgirefモジュール

wsgirefモジュールを使用して私たち自身のWebフレームワークのソケットサーバーの一部を書き置き換えます。

ログイン機能は、ファイルに対応しています。

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta http-equiv="content-Type" charset="UTF-8">
    <meta http-equiv="x-ua-compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>login</title>
</head>
<body>
<h1>登录页面</h1>
<h1>This is login page!</h1>
<a href="https://blog.csdn.net/qq_41964425/article/category/8083068" target="_blank">CSDN</a>

<p>时间:@@xx@@</p>    <!--提前定义好特殊符号-->
</body>
</html>

Pythonコード:

from time import strftime
from wsgiref.simple_server import make_server


# 将返回不同的内容部分封装成函数
def index(url):
    with open('index.html', 'rb') as f: return f.read()


def home(url):
    with open('home.html', 'rb') as f: return f.read()


def login(url):
    """实现动态网页"""
    now_time = str(strftime('%F %T'))  # 获取当前格式化时间
    with open('login.html', 'r', encoding='UTF-8') as f:
        s = f.read()
    # 在网页中定义好特殊符号,用动态的数据去替换定义好的特殊符号
    s = s.replace('@@xx@@', now_time)
    return bytes(s, encoding='UTF-8')


# 定义一个url和实际要执行的函数的对应关系
url_list = [
    ('/index', index),
    ('/home', home),
    ('/login', login),
]


def run_server(environ, start_response):
    # 设置HTTP响应的状态码和头消息
    start_response('200 OK', [('Content-Type', 'text/html;charset=utf8'), ])
    url = environ['PATH_INFO']  # 取到用户输入的url

    func = None
    for i in url_list:
        if url == i[0]:
            func = i[1]
            break
    response = func(url) if func else b'404 not found!'

    return [response, ]


if __name__ == '__main__':
    httpd = make_server('127.0.0.1', 8080, run_server)
    print('Wsgiref has started...')
    httpd.serve_forever()

おすすめ

転載: www.cnblogs.com/gqy02/p/11304518.html
おすすめ