web框架

本文深入探讨了Python在Web开发中的应用,包括Django、Flask和Tornado等主流框架的特点,以及它们在socket、页面路由和模板渲染方面的处理方式。同时,详细解析了HTTP协议的工作原理,包括其基于请求-响应模式的特性、无连接和无状态的属性,以及完整的事务处理流程。

一.导读

1.web应用:运行在浏览器上的应用。

2.c/s  b/s 架构:

client/server:客户端/服务器架构,C++

brower/server:浏览器/服务器架构,Java,Python

3.python  web框架:

Django:socket用的是wsgiref,页面路由用的自己写的,模板渲染用的自己写的,特点:功能全面。

Flask:socket用的是第三方,页面路由用的自己写的,模板渲染用的自己写的,特点:小而轻。

Tornado:socket用的是自己写的,页面路由用的自己写的,模板渲染用的自己写的,特点:支持高并发。

二.HTTP协议

1.什么是http协议?

HTTP(HyperText Transport Protocol)指的是超文本传输协议,它是基于TCP/IP协议基础上的应用层协议,底层实现还是socket,它是基于请求-响应模式:通信一定是从客户端开始,服务器端接收到客户端一定会做出对应响应。

无连接:一次连接只完成一次请求-响应,请求-响应完毕后会立即断开连接。

无状态:协议不对任何一次通信状态和任何数据进行保存。

2.http工作原理(事务)

一次http操作称之为一个事务,工作过程可以分为四步:

1.客户端与服务器建立连接;

2.客户端发生一个http协议指定格式的请求;

3.服务器端接收请求后,响应一个http协议指定格式的响应;

4.客户端将服务器的响应显示展现给用户。

import socket
PORT = 9999
server = socket.socket()
server.bind(('127.0.0.1', PORT))
server.listen(5)
print("服务器启动:http://127.0.0.1:%s" % PORT)

while True:
    brower, addr = server.accept()
    req_data = brower.recv(1024).decode('utf-8')
    # print(req_data)

    # 响应报文
    # 遵循http协议返回数据:响应行 响应头 响应体
    brower.send(b'HTTP/1.1 200 OK\r\n')  # 响应行(必须),以\r\n结束
    brower.send(b'Content-type:text/html\r\n')  # 响应头(可选),服务于响应头
    brower.send(b'\r\n')  # 响应规则与响应体内容之间还需要一个\r\n进行分割
    brower.send(b'hahaha')  # 响应体(可选)
    brower.send(b'<h1>hello world</h1>')
    
    brower.close()  # 必须关闭每一次的连接


# 请求报文
'''
GET / HTTP/1.1
Host: 127.0.0.1:9999
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.75 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9


GET /favicon.ico HTTP/1.1  # /favicon.ico指的是页面头的图标
Host: 127.0.0.1:9999
Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.75 Safari/537.36
Accept: image/webp,image/apng,image/*,*/*;q=0.8
Referer: http://127.0.0.1:9999/
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
'''
基础b/s架构

3.http处理响应

import socket
PORT = 9999
server = socket.socket()
server.bind(('127.0.0.1', PORT))
server.listen(5)
print("服务器启动:http://127.0.0.1:%s" % PORT)


def index():
    pass


def login():
    pass


def ico():
    with open('1.jpg', 'rb') as f:
        data = f.read()
    return data
    

func_dic = {
    '/': index,
    '/index': index,
    '/login': login,
    '/favicon.ico': ico
}

while True:
    brower, addr = server.accept()
    req_data = brower.recv(1024).decode('utf-8')
    # print(req_data)

    # 响应报文
    # 遵循http协议返回数据:响应行 响应头 响应体
    brower.send(b'HTTP/1.1 200 OK\r\n')  # 响应行(必须),以\r\n结束
    brower.send(b'Content-type:text/html\r\n')  # 响应头(可选),服务于响应头
    brower.send(b'\r\n')  # 响应规则与响应体内容之间还需要一个\r\n进行分割

    # GET / HTTP/1.1
    # GET /favicon.ico HTTP/1.1
    path = req_data.split('\r\n')[0].split(' ')[1]  # 请求路径
    # 根据路径,处理不同的请求方法
    if path in func_dic:
        res_dic = func_dic[path]()
    res_dic = b'<h1 style="text-align: center">404</h>'
    brower.send(res_dic)  # 响应体(可选)
    brower.close()  # 必须关闭每一次的连接
请求分配

基于上面的基础b/s架构,可以根据请求http协议数据,解析出请求路径,根据具体路径完成业务逻辑,的方法,完成对应的响应。

1.由于业务逻辑会不断的增加,所以业务逻辑要进行分层单独处理;

2.路径与业务处理方法对应关系也会越来越多,越来越复杂,也可以分离单独处理;

3.自定义服务器功能不健全,稳定性差,可以选择第三方

server.py

import socket
from wsgi协议.urls import url_dic
PORT = 9999
server = socket.socket()
server.bind(('127.0.0.1', PORT))
server.listen(5)
print("服务器启动:http://127.0.0.1:%s" % PORT)

while True:
    brower, addr = server.accept()
    req_data = brower.recv(1024).decode('utf-8')
    # print(req_data)

    # 响应报文
    # 遵循http协议返回数据:响应行 响应头 响应体
    brower.send(b'HTTP/1.1 200 OK\r\n')  # 响应行(必须),以\r\n结束
    brower.send(b'Content-type:text/html\r\n')  # 响应头(可选),服务于响应头
    brower.send(b'\r\n')  # 响应规则与响应体内容之间还需要一个\r\n进行分割

    # GET / HTTP/1.1
    # GET /favicon.ico HTTP/1.1
    url = req_data.split('\r\n')[0].split(' ')[1]  # 请求路径
    # 根据路径,处理不同的请求方法
    if url in url_dic:
        res_dic = url_dic[url]()
    res_dic = b'<h1 style="text-align: center">404</h>'  # 响应错误时返回404
    brower.send(res_dic)  # 响应体(可选)
    brower.close()  # 必须关闭每一次的连接


urls.py

from wsgi协议.views import *

url_dic = {
    '/': index,
    '/index': index,
    '/login': login,
    '/favicon.ico': ico
}


views.py

def index():
    pass


def login():
    pass


def ico():
    with open('1.jpg', 'rb') as f:
        data = f.read()
    return data
分层请求分配处理

4.状态码

# 1打头:消息通知
# 2打头:请求成功
# 3打头:重定向
# 4打头:客户端错误
# 5打头:服务器端错误

三.WSGI协议

利用第三方wsgiref服务器完成http请求-响应:

通过wsgiref模块创建server时,有三个参数分别是:Host,Port,app,其中app时一个回调函数,该回调函数有两个参数:environ和response;environ是一个字典,请求的数据都被解析在该字典中,用response来规定http响应的结果。

server.py

from wsgiref import simple_server
from wsgi协议.urls import url_dic
PORT = 8888


# 回调函数
def app(environ, response):
    # 请求的数据都被解析在environ字典中
    # 请求方式的key:REQUEST_METHOD  # 'REQUEST_METHOD': 'GET'
    # 请求的路径的key:PATH_INFO  # 'PATH_INFO': '/'
    print(environ)
    # 用response来规定http响应的结果
    response('200 OK', [('Content-type', 'text/html')])

    # 数据的获取

    # 解析给key,得到数据
    method = environ['REQUEST_METHOD']  # 请求方法
    res_dic = {}
    url = ''
    if method == 'GET':
        url = environ['PATH_INFO']  # 请求路径
        # 在GET方法中:数据在environ中的QUERY_STRING对应的value
        res_str = environ['QUERY_STRING']
        if res_str:
            res_list = res_str.split('&')
            for i in res_list:
                data_list = i.split('=')
                res_dic[data_list[0]] = data_list[1]
    elif method == 'POST':  # 在POST方法中:数据存放的io流'wsgi.input': <_io.BufferedReader name=552>;数据长度'CONTENT_LENGTH': '40'
        length = int(environ['CONTENT_LENGTH'])
        if length == 0:
            return
        res_str = environ['wsgi.input'].read(length).decode('utf-8')

        res_list = res_str.split('&')

        for i in res_list:
            data_list = i.split('=')
            if i is res_list[-1]:
                url = '/' + data_list[0]
                # print(url)
                continue
            res_dic[data_list[0]] = data_list[1]
        # print(res_dic)

    req_dic = b'<h1 style="text-align: center">404</h1>'
    if url in url_dic:
        req_dic = url_dic[url](res_dic)

    # print(res_dic)

    # 返回的是装有二进制数据的列表
    return [req_dic]


if __name__ == '__main__':
    server = simple_server.make_server('127.0.0.1', PORT, app=app)  # 通过wsgiref创建server
    print('服务器启动:http://127.0.0.1:%s' % PORT)
    # 保持server一直运行
    server.serve_forever()


views.py

import pymysql
from jinja2 import Template


def execute(sql, args):
    conn = pymysql.connect(
        host='127.0.0.1',
        port=3306,
        user='root',
        password='root',
        db='db1',
        charset='utf8',
        autocommit=True
    )
    cursor = conn.cursor(pymysql.cursors.DictCursor)
    affect_row = cursor.execute(sql, args=args)
    return affect_row


def index(dic):
    pass


def login(dic):
    # print(dic)
    name = dic['usr']
    pwd = dic['pwd']
    sql = "select * from user where name=%s and pwd=%s"
    args = [name, pwd]
    row = execute(sql, args)
    with open('login.html', 'rt') as f:
        msg = f.read()
    tem = Template(msg)
    if row:
        res = 'login success'
    else:
        res = 'login failed'
    msg = tem.render(result=res)
    return msg.encode('utf-8')


def register(dic):
    pass


def ico(dic):
    with open('timg.jpg', 'rb') as f:
        data = f.read()
    return data

login.html

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

urls.py

from wsgi协议.views import *

url_dic = {
    '/': index,
    '/index': index,
    '/login': login,
    '/favicon.ico': ico
}

deom.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="http://127.0.0.1:8888" method="post">
    <input type="text" name="usr">
    <br>
    <input type="password" name="pwd">
    <br>
    <input type="submit" value="login" name="login">
</form>
</body>
</html>
简单登录功能

 

转载于:https://www.cnblogs.com/wangke0917/p/10432607.html

乐播投屏是一款简单好用、功能强大的专业投屏软件,支持手机投屏电视、手机投电脑、电脑投电视等多种投屏方式。 多端兼容与跨网投屏:支持手机、平板、电脑等多种设备之间的自由组合投屏,且无需连接 WiFi,通过跨屏技术打破网络限制,扫一扫即可投屏。 广泛的应用支持:支持 10000+APP 投屏,包括综合视频、网盘与浏览器、美韩剧、斗鱼、虎牙等直播平台,还能将央视、湖南卫视等各大卫视的直播内容一键投屏。 高清流畅投屏体验:腾讯独家智能音画调校技术,支持 4K 高清画质、240Hz 超高帧率,低延迟不卡顿,能为用户提供更高清、流畅的视觉享受。 会议办公功能强大:拥有全球唯一的 “超级投屏空间”,扫码即投,无需安装。支持多人共享投屏、远程协作批注,PPT、Excel、视频等文件都能流畅展示,还具备企业级安全加密,保障会议资料不泄露。 多人互动功能:支持多人投屏,邀请好友加入投屏互动,远程也可加入。同时具备一屏多显、语音互动功能,支持多人连麦,实时语音交流。 文件支持全面:支持 PPT、PDF、Word、Excel 等办公文件,以及视频、图片等多种类型文件的投屏,还支持网盘直投,无需下载和转格式。 特色功能丰富:投屏时可同步录制投屏画面,部分版本还支持通过触控屏或电视端外接鼠标反控电脑,以及在投屏过程中用画笔实时标注等功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值