web应用简介

一,web应用的介绍

  本质:可以通过web访问的应用程序,一般是B/S模式(用户通过浏览器访问程序)

  优点:

    1,操作过程简单,只需要有了个使用的浏览器(Google Chrome)

    2,耗费的硬盘空间很少。

    3,服务器实时更新。

    4,基于B/S开发的应用程序可以很好的结合其他应用程序的功能。

    5,可以跨平台使用。

  缺点:

    1,强调浏览器的适用性,若是弃用某些操作平台或版本就会影响大量的客户。

    2,基于互联网运行,网络连接出问题时,应用将不能正常使用。

    3,由于绝大多数情况不能离线使用,因而损失了很多的灵活性。

    4,完全依赖服务商的可及性。公司倒闭了,服务器及不能使用了。

    5,提供方公司具有这更大的控制权。

    6,公司可以检索任何用户的功能,这可能引起隐私安全的问题。

二,关于HTTP协议

  HTTP(Hyper Text Transfer Protocol)协议就是超文本传输协议,是用于万维网(WWW:World Wide Web )服务器与本地浏览器之间传输超文本的传送协议。规定了客户端与服务器消息传输的格式

  特点:

    1:基于TCP/ip协议作用于应用层的协议

    2:基于请求-响应模式

      HTTP协议规定,请求从客户端发出,最后服务器端响应该请求并 返回。换句话说,肯定是先从客户端开始建立通信的,服务器端在没有 接收到请求之前不会发送响应。(请求必定由客户端发出,二服务器回复相应)

    3:无状态保存

      HTTP是一种不保存状态,即无状态(stateless)协议。HTTP协议 自身不对请求和响应之间的通信状态进行保存。也就是说在HTTP这个 级别,协议对于发送过的请求或响应都不做持久化处理。     

    4:无连接

      无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。

  请求数据的格式:

    1:请求首行

    2:请求头(键值对形式)

    3:请求体(post携带数据)

  响应数据的格式:

    1:响应首行

    2:响应头(键值对形式)

    3:相应体(post请求携带的数据)

  响应码:

    1xx:服务器已经成功接受到你的数据正在处理,你可以继续提交其他数据

    2xx:请求成功 服务器已经将你请求的数据发送给你了

    3xx:重指定(连接到第三方网址)

    4xx:请求资源不存在

    5xx:服务器错误

  动静态网页:

    静态网页:

      页面上的数据都是写死的,万年不变。

    动态网页:

      页面上的数据是从后端动态获取的。

      比如后端获取当前时间。

      后端获取数据库然后传递给前端给页面。

  模板渲染:

    后端生成的数据直接传递给前端页面使用(并且前端页面可以灵活的操作改数据)>>> 模板语法

    ps:模板语法需要依赖第三方模块。(例如jinja2)

  案例一:自制web框架

import socket
"""
请求首行
b'GET / HTTP/1.1

请求头(一大堆kv键值对)
Host: 127.0.0.1:8080

Connection: keep-alive

Upgrade-Insecure-Requests: 1

User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3

Accept-Encoding: gzip, deflate, br

Accept-Language: zh-CN,zh;q=0.9,en;q=0.8



请求体
'
"""
server = socket.socket()  # 不传参数默认就是TCP协议
server.bind(('127.0.0.1',8080))
server.listen(5)

while True:
    conn, addr = server.accept()  # 阻塞 等待客户端链接
    data = conn.recv(1024)
    conn.send(b'HTTP/1.1 200 OK

')
    print(data)
    # 手动处理http数据获取用户访问的路径
    current_path = data.decode('utf-8').split('
')[0].split(' ')[1]
    if current_path == '/index':
        # 路由匹配上之后返回index
        # conn.send(b'<h1>index</h1>')
        with open('index.html','rb') as f:
            conn.send(f.read())
    else:
        # 当匹配不上的时候统一返回404
        conn.send(b'404')
    conn.close()

  案例二:基于wsgiref框架

from wsgiref.simple_server import make_server
from urls import *
def run(env,response):
    # env:包含请求信息的dict对象
    # response:发送HTTP相应的函数
    response('200 OK',[('username','jason'),('password','123')])  # 固定写法 后面列表里面一个个元祖会以响应头kv键值对的形式返回给客户端
    # 获取用户访问的路径
    current_path = env.get('PATH_INFO')
    # 定义一个存储函数名的变量名
    func = None
    # 循环比对路由与试图函数的映射关系
    for url_map in urls:  # url_map = ('/index',index)
        if current_path == url_map[0]:
            # 匹配成功直接调用函数,并且结束循环
            func = url_map[1]
            break
    if func:
        res = func(env)
    else:
        # 没有用户想要访问的路径,则返回一个错误信息
        res = error(env)
        # 最后进行编码处理
    return [res.encode('utf-8')]
if __name__ == '__main__':
    server = make_server('127.0.0.1',8080,run)
    server.serve_forever()

    urls.py:

from views import *
urls = [
    ('/index',index),
    ('/login',login),
    ('/reg',reg),
    ('/get_time',get_time),
    ('/get_user',get_user),
    ('/get_db',get_db),
]

    view.py:

def index(env):
    return 'index'

def login(env):
    return 'login'

def reg(env):
    return 'reg'

def get_time(env):
    # 先获取当前时间
    current_time = time.strftime('%Y-%m-%d %X')
    # 打开html文件读取内容返回给客户端
    with open(r'templates/get_time.html','r',encoding='utf-8') as f:
        data = f.read()
    # 因为是以r模式打开的文件,所有获取到的内容就是一堆字符串
    res = data.replace('@@time@@',current_time)  # 字符串的替换
    return res

def get_user(env):

    with open(r'templates/get_user.html','r',encoding='utf-8') as f:
        data = f.read()
    tmp = Template(data)
    # 将字典传递给前端页面 前端通过变量名user_dic就可以获取到该字典
    return tmp.render(user_dic={'name':"jason",'password':'123'})


def get_db(env):
    # 连接数据库 获取数据 渲染到前端页面
    conn = pymysql.connect(
        host = '127.0.0.1',
        port = 3306,
        user = 'root',
        password = '123',
        database = 'day54',
        charset = 'utf8',
        autocommit = True
    )
    cursor = conn.cursor(pymysql.cursors.DictCursor)
    cursor.execute('select * from userinfo')
    user_dict= cursor.fetchall()  # [{},{},{},{}]
    with open(r'templates/get_db.html','r',encoding='utf-8') as f:
        data = f.read()
    tmp = Template(data)
    return tmp.render(user_dict=user_dict)

def error(env):
    return '404 error'

    get_time.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
@@time@@
</body>
</html>

    get_user.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<!--jinja2支持的格式-->
<p>{{ user_dic }}</p>
<p>{{ user_dic.name }}</p>
<p>{{ user_dic['password'] }}</p>
<p>{{ user_dic.get('name') }}</p>
</body>
</html>

    get_db.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
    <div class="row">
        <div class="col-md-8 col-md-offset-2">
            <table class="table table-hover table-striped table-bordered">
                <thead>
                    <tr>
                        <th>id</th>
                        <th>name</th>
                        <th>password</th>
                    </tr>
                </thead>
                <tbody>
                    <!--jinja2的for循环开始-->
                    {% for user in user_dict %}  <!--[{},{},{},{}]-->
                        <tr>
                            <td>{{ user.id }}</td>
                            <td>{{ user.name }}</td>
                            <td>{{ user.password }}</td>
                        </tr>
                    {% endfor %}
                    <!--jinja2的for循环结束-->
                </tbody>
            </table>
        </div>
    </div>
</div>
{{ user_dict }}  <!--[{},{},{},{}]-->
</body>
</html>

  

原文地址:https://www.cnblogs.com/ay742936292/p/10979357.html