zoukankan      html  css  js  c++  java
  • WEB框架

    WEB框架本质

    通常为B/S架构,浏览器作为客户端,服务器为服务端。优点:升级维护方便。

    浏览器

    功能:发送/解析请求(request)

    请求格式

    1)GET

    GET请求格式
    
          “GET /  HTTP/1.1  
    ”
    
             k1:v1
    
                      k2:v2
    
    
    
          只有请求头,没有请求体
    发送

    响应

    特点:

    • 没有请求体
    • 数据必须在1K之内!
    • GET请求数据会暴露在浏览器的地址栏中   ——   缺点

    GET请求常用的操作:

    • 在浏览器的地址栏中直接给出URL,那么就一定是GET请求
    • 点击页面上的超链接也一定是GET请求
    • 提交表单时,表单默认使用GET请求,但可以设置为POST

    2) POST

    POST:请求格式
    
          “POST / HTTP/1.1 
    ”
    
          k1:v1
    
                       k2:v2
    
    
          有请求头和请求体
    
    POST /index HTTP/1.1
                Host: 127.0.0.1:8080
                Connection: keep-alive
                Cache-Control: max-age=0
                Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
                User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.89 Safari/537.36
                HTTPS: 1
                Accept-Encoding: gzip, deflate, sdch
                Accept-Language: zh-CN,zh;q=0.8
                Cookie: csrftoken=hNmu2JOtntGMN0hSRSPmMQk2newEb3o8zb6pXW5Cc3m54IaA5VlTkUvqWsFezpni
    请求(发送)
    200 OK
                Cache-Control:public, max-age=15
                Connection:keep-alive
                Content-Encoding:gzip
                Content-Type:text/html; charset=utf-8
                Date:Wed, 14 Jun 2017 01:21:17 GMT
                Expires:Wed, 14 Jun 2017 01:21:33 GMT
                Last-Modified:Wed, 14 Jun 2017 01:21:03 GMT
                Transfer-Encoding:chunked
                Vary:Accept-Encoding
                X-Frame-Options:SAMEORIGIN
                X-UA-Compatible:IE=10
    
    注意: 用户在页面看到的内容“字符串”(看到页面效果,由于浏览器解析)
    响应

    响应:
    Header

    Body

    HTTP

    上面的GET、POST请求属于HTTP请求,浏览器和WEB服务端通信需要一个规则,这个规则就是HTTP协议简单理解为规定消息格式

    特点:是无状态、短连接

    自定义WEB框架

    流程

    A)自定义soket服务端,处理请求相关的数据 ——Wsgiref / uWSGI / Gunicorn

    B)通过URL——>函数——>根据函数的逻辑(取数据)

    C)把数据填充到HTML页面(字符串替换)

    WEB框架分类

      1.a、b、c都是自己的             Tornado

      2.a用别人的,b、c用自己的  Django

      3.a、c用别人的,b用自己的  Flask

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

    import socket
       
    def handle_request(client):
        buf = client.recv(1024)
        client.send("HTTP/1.1 200 OK
    
    ")
        client.send("Hello, Seven")
       
    def main():
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.bind(('localhost',8000))
        sock.listen(5)
       
        while True:
            connection, address = sock.accept()
            handle_request(connection)
            connection.close()
       
    if __name__ == '__main__':
        main()

      上述通过socket来实现了其本质,而对于真实开发中的python web程序来说,一般会分为两部分:服务器程序和应用程序服务器程序负责对socket服务器进行封装,并在请求到来时,对请求的各种数据进行整理应用程序则负责具体的逻辑处理。为了方便应用程序的开发,就出现了众多的Web框架,例如:Django、Flask、web.py 等。不同的框架有不同的开发方式,但是无论如何,开发出的应用程序都要和服务器程序配合,才能为用户提供服务。这样,服务器程序就需要为不同的框架提供不同的支持。这样混乱的局面无论对于服务器还是框架,都是不好的。对服务器来说,需要支持各种不同框架,对框架来说,只有支持它的服务器才能被开发出的应用使用。这时候,标准化就变得尤为重要。我们可以设立一个标准,只要服务器程序支持这个标准,框架也支持这个标准,那么他们就可以配合使用。一旦标准确定,双方各自实现。这样,服务器可以支持更多支持标准的框架,框架也可以使用更多支持标准的服务器。

    WSGI(Web Server Gateway Interface)是一种规范,它定义了使用python编写的web app与web server之间接口格式,实现web app与web server间的解耦。我们需要在WSGI接口之上能进一步抽象,让我们专注于用一个函数处理一个URL,至于URL到函数的映射,就交给Web框架来做。

    python标准库提供的独立WSGI服务器称为wsgiref。

    from wsgiref.simple_server import make_server
      
      
    def RunServer(environ, start_response):
        start_response('200 OK', [('Content-Type', 'text/html')])
        return [bytes('<h1>Hello, web!</h1>', encoding='utf-8'), ]
      
      
    if __name__ == '__main__':
        httpd = make_server('', 8000, RunServer)
        print("Serving HTTP on port 8000...")
        httpd.serve_forever()

     web请求生命周期

    自定义web框架

    import socket
    
    sk = socket.socket()
    sk.bind(("127.0.0.1", 8000))
    sk.listen(5)
    
    while True:
        conn, addr = sk.accept()
        data = conn.recv(8096)
        print(data)  # data是浏览器传过来的请求信息,bytes类型
        data_str = str(data, encoding="utf8")
        l1 = data_str.split("
    ")
        l2 = l1[0].split()
        url = l2[1]
        # 根据url的不同,返回不同的内容
        if url == "/index/":
            body = "这是index页面"
        elif url == "/home/":
            body = "这是home页面"
        else:
            body = "404找不到"
        # 服务端回复消息
        conn.send(bytes("HTTP/1.1 200 OK
    Content-Type:text/html; charset=utf-8
    
    <h1>{}</h1>".format(body), encoding="utf8"))
        conn.close()
    soket实例
    from wsgiref.simple_server import make_server
    
    def index():
        with open("index.html", encoding="utf8") as f:
            data = f.read()
    
        # 连接数据库
        import pymysql
        # 连接
        conn = pymysql.connect(host="localhost", user="root", password="root1234", database="s8", charset="utf8")  # 没有-
        # 获取光标
        cursor = conn.cursor()
        # 写sql语句
        sql = "select name, pwd from userinfo where id =1;"
        cursor.execute(sql)
        ret = cursor.fetchone()
        print(ret)
        # 将数据库中的数据填充到HTML页面
        new1_data = data.replace("@@2@@", ret[0])
        new2_data = new1_data.replace("##3##", ret[1])
    
        return new2_data
    
    def home():
        return "这是home页面"
    
    def login():
        with open("login.html", encoding="utf8") as f:
            data = f.read()
        import time
        time_str = str(time.time())
        new_data = data.replace("@@2@@", time_str)
        return new_data
    
    URL_FUNC = [
        ("/index/", index),
        ("/home/", home),
        ("/login/", login),
    ]
    
    def run_server(environ, start_response):
        start_response('200 OK', [('Content-Type', 'text/html;charset=utf8')])  # 设置HTTP响应的状态码和头信息
        url = environ['PATH_INFO']  # 取到用户输入的url
        print("--->url:", url)
        # 根据url的不同,返回不同的内容
        func_name = None
        for i in URL_FUNC:
            if url == i[0]:  # 如果能找到对应关系,就把函数名拿到
                func_name = i[1]
                break
        # 拿到可以执行的函数,执行函数拿到结果
        if func_name:
            body = func_name()
        else:
            body = "404找不到这个页面"
    
        return [bytes("<h1>{}</h1>".format(body), encoding="utf8"),]
    
    
    if __name__ == '__main__':
        httpd = make_server('', 8000, run_server)
        print("Serving HTTP on port 8000...")
        httpd.serve_forever()
    wsgiref模块示例从数据库取数据
    from wsgiref.simple_server import make_server
    import jinja2
    
    def index():
        with open("index.html", encoding="utf8") as f:
            data = f.read()
    
        # 连接数据库
        import pymysql
        # 连接
        conn = pymysql.connect(host="localhost", user="root", password="root1234", database="s8", charset="utf8")  # 没有-
        # 获取光标
        cursor = conn.cursor()
        # 写sql语句
        sql = "select name, pwd from userinfo where id =1;"
        cursor.execute(sql)
        ret = cursor.fetchone()
        print(ret)
        # 将数据库中的数据填充到HTML页面
        new1_data = data.replace("@@2@@", ret[0])
        new2_data = new1_data.replace("##3##", ret[1])
        return new2_data
    
    def home():
        return "这是home页面"
    
    def userlist():
        with open("userlist.html", encoding="utf8") as f:
            data = f.read()
        # 生成了一个jinja2的模板对象
        template = jinja2.Template(data)
        # 相当于字符串替换
        new_data = template.render({
            "user_list": [
                {"name": "jianchao", "pwd": "1234"},
                {"name": "liyan", "pwd": "5678"}
            ]
        })
        return new_data
    
    def login():
        with open("login.html", encoding="utf8") as f:
            data = f.read()
        import time
        time_str = str(time.time())
        new_data = data.replace("@@2@@", time_str)
        return new_data
    
    URL_FUNC = [
        ("/index/", index),
        ("/home/", home),
        ("/login/", login),
        ("/userlist/", userlist),
    ]
    
    def run_server(environ, start_response):
        start_response('200 OK', [('Content-Type', 'text/html;charset=utf8')])  # 设置HTTP响应的状态码和头信息
        url = environ['PATH_INFO']  # 取到用户输入的url
        print("--->url:", url)
        # 根据url的不同,返回不同的内容
        func_name = None
        for i in URL_FUNC:
            if url == i[0]:  # 如果能找到对应关系,就把函数名拿到
                func_name = i[1]
                break
        # 拿到可以执行的函数,执行函数拿到结果
        if func_name:
            body = func_name()
        else:
            body = "404找不到这个页面"
    
        return [bytes("<h1>{}</h1>".format(body), encoding="utf8"),]
    
    
    if __name__ == '__main__':
        httpd = make_server('', 9000, run_server)
        print("Serving HTTP on port 8000...")
        httpd.serve_forever()
    wsgiref模块示例 jinja2
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>index</title>
    </head>
    <body>
    <h1>姓名:@@2@@</h1>
    <h1>密码:##3##</h1>
    
    </body>
    </html>
    index.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Title</title>
        <link rel="stylesheet" href="bootstrap-3.3.7/css/bootstrap.min.css">
    </head>
    <body>
    <form action="">
        <p>姓名<input type="text"></p>
        <p>密码<input type="password"></p>
        <p><input type="submit" value="登录"></p>
    </form>
    
    @@2@@
    <script src="jquery-3.2.1.min.js"></script>
    </body>
    </html>
    login.html
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="x-ua-compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1">
      <title>Title</title>
    </head>
    <body>
        <ul>
            {% for user in user_list %}
            <li>{{user.name}}|{{user.pwd}}</li>
            {% endfor %}
        </ul>
    </body>
    </html>
    userlist.html
  • 相关阅读:
    洛谷P2522 [HAOI2011]Problem b(莫比乌斯反演)
    洛谷P3327 [SDOI2015]约数个数和(莫比乌斯反演)
    Informatica PowerCenter 常用转换组件一览表
    Informatica_(3)组件
    Informatica_(2)第一个例子
    Informatica_(1)安装
    InformaticaPowerCenter调用存储过程
    Informatica 9.5.1 安装配置
    Linux字符集的查看及修改
    Redis-3.2.9集群配置(redis cluster)
  • 原文地址:https://www.cnblogs.com/huyangblog/p/8480651.html
Copyright © 2011-2022 走看看