美文网首页
web框架的本质

web框架的本质

作者: 莫辜负自己的一世韶光 | 来源:发表于2018-11-02 19:16 被阅读0次

所有的web应用本质上就是一个socket服务端,而用户的浏览器就是一个socket客户端,这样我们就可以实现一个web框架了.

  • 半成品自定义的web框架

用户的浏览器一输入网址,会给服务端发送数据,那浏览器会发送什么数据?怎么发?这个谁来定? 你这个网站是这个规定,他那个网站按照他那个规定,这互联网还能玩么?

所以,必须有一个统一的规则,让大家发送消息、接收消息的时候有个格式依据,不能随便写。

这个规则就是HTTP协议,以后浏览器发送请求信息也好,服务器回复响应信息也罢,都要按照这个规则来。

HTTP协议主要规定了客户端和服务器之间的通信格式,那HTTP协议是怎么规定消息格式的呢?

让我们首先打印下我们在服务端接收到的消息是什么。

这样访问网页的时候,会出现如下界面:

这是因为响应的时候,必须按照一定的格式才可以.

  • 可以响应成功的简单版本的自定义的Web框架,带响应行的

  • 根据不同的路径返回不同的内容

这样并不能很好的响应不同的请求,可以根据解析请求的内容,根据请求不同的URL,返回不同的内容.


  • 用函数实现不同的路径,不同的处理方式.可以使用一个列表,不同的路径,对应不同的函数处理方法.
# encoding:utf-8
__author__ = 'Fioman'
__date__ = '2018/11/2 17:08'
import socket

sock = socket.socket()
sock.bind(('127.0.0.1', 8000))
sock.listen()


def index(url):
    s = "这是{}页面!".format(url)
    return bytes(s, encoding='utf-8')


def home(url):
    s = "这是{}页面!".format(url)
    return bytes(s, encoding='utf-8')


func_urls = [
    ('/index/', index),
    ('/home/', home),
]
while True:
    conn, addr = sock.accept()
    data = conn.recv(8096)
    data = str(data, encoding='utf-8')
    requestLine = data.split('\r\n')[0]
    url = requestLine.split(' ')[1]

    # 路径和函数的对应关系
    func = None
    for i in func_urls:
        if i[0] == url:
            func = i[1]
            break

    if func:
        response = func(url)
    else:
        response = b'404 not found!'
    conn.send(b'HTTP/1.1 200 OK')
    conn.send(response)

    conn.close()

sock.close()


  • 返回不同的HMTL文件

本质就是读取本地的HTML文件,然后以二进制数据的形式发送给客户端

# encoding:utf-8
__author__ = 'Fioman'
__date__ = '2018/11/2 17:08'
import socket

sock = socket.socket()
sock.bind(('127.0.0.1', 8000))
sock.listen()


def index(url):
    with open('index.html', 'rb', encoding='utf-8') as f:
        ret = f.read()
    return ret


def home(url):
    with open('home.html', 'rb', encoding='utf-8') as f:
        ret = f.read()
    return ret


func_urls = [
    ('/index/', index),
    ('/home/', home),
]
while True:
    conn, addr = sock.accept()
    data = conn.recv(8096)
    data = str(data, encoding='utf-8')
    requestLine = data.split('\r\n')[0]
    url = requestLine.split(' ')[1]

    # 路径和函数的对应关系
    func = None
    for i in func_urls:
        if i[0] == url:
            func = i[1]
            break

    if func:
        response = func(url)
    else:
        response = b'404 not found!'
    conn.send(b'HTTP/1.1 200 OK')
    conn.send(response)

    conn.close()

sock.close()


  • 返回动态网页

动态网页的实现,无非就是字符串的替换

  • 服务器程序和应用程序

对于真实开发中的python web程序来说,一般会分为两部分:服务器程序和应用程序。

服务器程序负责对socket服务器进行封装,并在请求到来时,对请求的各种数据进行整理。

应用程序则负责具体的逻辑处理。为了方便应用程序的开发,就出现了众多的Web框架,例如:Django、Flask、web.py 等。不同的框架有不同的开发方式,但是无论如何,开发出的应用程序都要和服务器程序配合,才能为用户提供服务。

这样,服务器程序就需要为不同的框架提供不同的支持。这样混乱的局面无论对于服务器还是框架,都是不好的。对服务器来说,需要支持各种不同框架,对框架来说,只有支持它的服务器才能被开发出的应用使用。

这时候,标准化就变得尤为重要。我们可以设立一个标准,只要服务器程序支持这个标准,框架也支持这个标准,那么他们就可以配合使用。一旦标准确定,双方各自实现。这样,服务器可以支持更多支持标准的框架,框架也可以使用更多支持标准的服务器。

WSGI(Web Server Gateway Interface)就是一种规范,它定义了使用Python编写的web应用程序与web服务器程序之间的接口格式,实现web应用程序与web服务器程序间的解耦。

常用的WSGI服务器有uwsgi、Gunicorn。而Python标准库提供的独立WSGI服务器叫wsgiref,Django开发环境用的就是这个模块来做服务器。

wsgiref

我们利用wsgiref模块来替换我们自己写的web框架的socket server部分

# encoding:utf-8
__author__ = 'Fioman'
__date__ = '2018/11/2 17:35'
import time
from wsgiref.simple_server import make_server


# 将返回不同的内容部分封装为函数
def index(url):
    with open('index.html', 'r', encoding='utf-8') as f:
        s = f.read()
        now = str(time.time())
        s = s.replace("@@xx@@", now)
    return bytes(s, encoding='utf-8')


def home(url):
    with open('home.html', 'rb', encoding='utf-8') as f:
        ret = f.read()
    return ret


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


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

    for i in func_urls:
        if i[0] == url:
            func = i[1]
            break

    if func:
        response = func(url)
    else:
        response = b'404 not found'

    return [response,]



if __name__ == '__main__':
    httpd = make_server('127.0.0.1', 8000, run_server)
    print('我在8000端口等你哦.........')
    # 启动服务
    httpd.serve_forever()

  • Jinja2模板
    虽然可以返回给用户HTML的内容以实现复杂的页面,但是如何返回动态的页面?

  • 自定义一套特殊的语法,进行替换

  • 使用开源工具jinja2,遵循其指定语法

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <h1>{{name}}</h1>

    <ul>
        {% for item in user_list %}
        <li>{{item}}</li>
        {% endfor %}
    </ul>

</body>
</html>
# encoding:utf-8
__author__ = 'Fioman'
__date__ = '2018/11/2 18:59'

from wsgiref.simple_server import make_server
from jinja2 import Template


def index():
    with open('index.html')
        ret = f.read()
        template = Template(ret)
        data = template.render(name='John Doe', user_list=['alex', 'eric'])

        return data.encode('utf-8')


def login():
    f = open('login.html')
    data = f.read()

    return data


def routers():
    urlpatterns = (
        ('/index/', index),
        ('/login/', login),
    )

    return urlpatterns


def run_server(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/html')])
    url = environ['PATH_INFO']
    urlpatterns = routers()

    func = None
    for item in urlpatterns:
        if item[0] == url:
            func = item[1]
            break

    if func:
        return func()
    else:
        return '404 not found'


if __name__ == '__main__':
    httpd = make_server('127.0.0.1', 8000, run_server)
    print("Serving HTTP on port 8000....")
    httpd.serve_forever()

总结一下

web框架的本质

socket服务端 和 浏览器客户端的通信

socket服务端功能划分:

  • a. 负责和浏览器收发消息(socket通信) -> wsgiref/uWsgi/gunicorn...

  • b. 根据用户访问的不同的URL的路径,执行不同的处理函数

  • c. 从HTML读取内容,并且完成字符串的替换. -> Jinja2模板语言

Web框架的分类

  • a. 框架自带a,b,c -> Tornado

  • b. 框架自带b和c,使用第三方的a -> Django

  • c. 框架自带b,使用第三方的a和c -> Flask

相关文章

  • Web框架本质

    Web框架本质 众所周知,对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个so...

  • web框架本质

    Python web frameworkshttps://wiki.python.org/moin/WebFram...

  • web框架本质

    来个简单的socket服务端 上述通过socket来实现了其本质,而对于真实开发中的python web程序来说,...

  • web框架的本质

    所有的web应用本质上就是一个socket服务端,而用户的浏览器就是一个socket客户端,这样我们就可以实现一个...

  • Tornado框架01-入门总概

    我们首先来谈谈web框架. web框架的本质其实就是socket服务端再加上业务逻辑处理, 比如像是Tornado...

  • Django框架的基本介绍和工具准备(一)

    一、Web应用框架----Django 事项注意点: web应用程序就是app、游戏、网站等之类的东西,本质就是一...

  • python全栈 part2 - 001 前端基础

    web框架本质 对于所有的Web应用, 本质上其实就是一个socket服务端,用户的浏览器其实是一个socket客...

  • Django基础:web框架

    一.web框架 1.web应用的本质 1.socket网络编程 架构:C/S架构 协议:TCP/UDP协议 传输层...

  • Django介绍 wep框架本质

    一 wep 框架的的本质 及自定义 wep 框架 Django是一个开放源代码的Web应用框架,由Python写成...

  • Python Web框架以及x-sendfile

    Python Web框架 Flask:轻量实用的Web框架 Tornado:Facebook的开源异步Web框架 ...

网友评论

      本文标题:web框架的本质

      本文链接:https://www.haomeiwen.com/subject/bsdcxqtx.html