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\r\n
請求頭(一大堆kv鍵值對)
Host: 127.0.0.1:8080\r\n
Connection: keep-alive\r\n
Upgrade-Insecure-Requests: 1\r\n
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36\r\n
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3\r\n
Accept-Encoding: gzip, deflate, br\r\n
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8\r\n
\r\n
請求體
'
"""
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\r\n\r\n')
    print(data)
    # 手動處理http數據獲取用戶訪問的路徑
    current_path = data.decode('utf-8').split('\r\n')[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>

 

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM