python終極篇 --- django (01)

来源:https://www.cnblogs.com/dalaoban/archive/2018/09/05/9594590.html
-Advertisement-
Play Games

服務端與瀏覽器收發信息: socket 套接字 是應用層和傳輸層之間一個虛擬層,是一個介面. 列印一下收到的消息是什麼>??? 那瀏覽器收到的消息是什麼? 通過以上對比,發現收發消息的格式都是一樣的 即為 HTTP協議格式 每個HTTP請求和響應都遵循相同的格式,一個HTTP包含Header和Bod ...


服務端與瀏覽器收發信息:

socket 套接字 是應用層和傳輸層之間一個虛擬層,是一個介面.

import socket  
  
sk = socket.socket()  
sk.bind(("127.0.0.1", 80))  
sk.listen()  
  
  
while True:  
    conn, addr = sk.accept()  
    data = conn.recv(8096)  
    conn.send(b"OK")  
    conn.close()  

 

列印一下收到的消息是什麼>???

將\r\n替換成換行看得更清晰點:

GET / HTTP/1.1  
Host: 127.0.0.1:8080  
Connection: keep-alive  
Cache-Control: max-age=0  
Upgrade-Insecure-Requests: 1  
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3355.4 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  
Cookie: csrftoken=CtHePYARJOKNx5oNVwxIteOJXpNyJ29L4bW4506YoVqFaIFFaHm0EWDZqKmw6Jm8  

那瀏覽器收到的消息是什麼?

 

通過以上對比,發現收發消息的格式都是一樣的---即為 HTTP協議格式

每個HTTP請求和響應都遵循相同的格式,一個HTTP包含Header和Body兩部分,其中Body是可選的。

HTTP響應的Header中有一個 Content-Type表明響應的內容格式。它的值如text/html; charset=utf-8。

text/html則表示是網頁,charset=utf-8則表示編碼為utf-8。

 

 

  

mport socket    
    
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)    
sock.bind(('127.0.0.1', 8000))    
sock.listen()    
    
while True:    
    conn, addr = sock.accept()    
    data = conn.recv(8096)    
    # 給回覆的消息加上響應狀態行    
    conn.send(b"HTTP/1.1 200 OK\r\n\r\n")      不加這行代碼返回不了數據
    conn.send(b"OK")    
    conn.close()    
自定義web框架
""" 
根據URL中不同的路徑返回不同的內容 
"""  
  
import socket  
  
sk = socket.socket()  
sk.bind(("127.0.0.1", 8080))  # 綁定IP和埠  
sk.listen()  # 監聽  
  
while True:  
    # 等待連接  
    conn, add = sk.accept()  
    data = conn.recv(8096)  # 接收客戶端發來的消息  
    # 從data中取到路徑  
    data = str(data, encoding="utf8")  # 把收到的位元組類型的數據轉換成字元串  
    # 按\r\n分割  
    data1 = data.split("\r\n")[0]  
    url = data1.split()[1]  # url是我們從瀏覽器發過來的消息中分離出的訪問路徑  
    conn.send(b'HTTP/1.1 200 OK\r\n\r\n')  # 因為要遵循HTTP協議,所以回覆的消息也要加狀態行  
    # 根據不同的路徑返回不同內容  
    if url == "/index/":  
        response = b"index"  
    elif url == "/home/":  
        response = b"home"  
    else:  
        response = b"404 not found!"  
  
    conn.send(response)  
    conn.close()  
根據不同的路徑返回不同的內容
""" 
根據URL中不同的路徑返回不同的內容--函數版 
"""  
  
import socket  
  
sk = socket.socket()  
sk.bind(("127.0.0.1", 8080))  # 綁定IP和埠  
sk.listen()  # 監聽  
  
  
# 將返回不同的內容部分封裝成函數  
def func(url):  
    s = "這是{}頁面!".format(url)  
    return bytes(s, encoding="utf8")  
  
  
while True:  
    # 等待連接  
    conn, add = sk.accept()  
    data = conn.recv(8096)  # 接收客戶端發來的消息  
    # 從data中取到路徑  
    data = str(data, encoding="utf8")  # 把收到的位元組類型的數據轉換成字元串  
    # 按\r\n分割  
    data1 = data.split("\r\n")[0]  
    url = data1.split()[1]  # url是我們從瀏覽器發過來的消息中分離出的訪問路徑  
    conn.send(b'HTTP/1.1 200 OK\r\n\r\n')  # 因為要遵循HTTP協議,所以回覆的消息也要加狀態行  
    # 根據不同的路徑返回不同內容,response是具體的響應體  
    if url == "/index/":  
        response = func(url)  
    elif url == "/home/":  
        response = func(url)  
    else:  
        response = b"404 not found!"  
  
    conn.send(response)  
    conn.close()  
根據不同的路徑返回不同的內容--函數版
""" 
根據URL中不同的路徑返回不同的內容--函數進階版 
"""  
  
import socket  
  
sk = socket.socket()  
sk.bind(("127.0.0.1", 8080))  # 綁定IP和埠  
sk.listen()  # 監聽  
  
  
# 將返回不同的內容部分封裝成不同的函數  
def index(url):  
    s = "這是{}頁面XX!".format(url)  
    return bytes(s, encoding="utf8")  
  
  
def home(url):  
    s = "這是{}頁面。。!".format(url)  
    return bytes(s, encoding="utf8")  
  
  
# 定義一個url和實際要執行的函數的對應關係  
list1 = [  
    ("/index/", index),  
    ("/home/", home),  
]  
  
while True:  
    # 等待連接  
    conn, add = sk.accept()  
    data = conn.recv(8096)  # 接收客戶端發來的消息  
    # 從data中取到路徑  
    data = str(data, encoding="utf8")  # 把收到的位元組類型的數據轉換成字元串  
    # 按\r\n分割  
    data1 = data.split("\r\n")[0]  
    url = data1.split()[1]  # url是我們從瀏覽器發過來的消息中分離出的訪問路徑  
    conn.send(b'HTTP/1.1 200 OK\r\n\r\n')  # 因為要遵循HTTP協議,所以回覆的消息也要加狀態行  
    # 根據不同的路徑返回不同內容  
    func = None  # 定義一個保存將要執行的函數名的變數  
    for item in list1:  
        if item[0] == url:  
            func = item[1]  
            break  
    if func:  
        response = func(url)  
    else:  
        response = b"404 not found!"  
  
    # 返回具體的響應消息  
    conn.send(response)  
    conn.close()  
根據不同的路徑返回不同的內容--函數進階版

 

""" 
根據URL中不同的路徑返回不同的內容--函數進階版 
返回獨立的HTML頁面 
"""  
  
import socket  
  
sk = socket.socket()  
sk.bind(("127.0.0.1", 8080))  # 綁定IP和埠  
sk.listen()  # 監聽  
  
  
# 將返回不同的內容部分封裝成不同的函數  
def index(url):  
    # 讀取index.html頁面的內容  
    with open("index.html", "r", encoding="utf8") as f:  
        s = f.read()  
    # 返回位元組數據  
    return bytes(s, encoding="utf8")  
  
  
def home(url):  
    with open("home.html", "r", encoding="utf8") as f:  
        s = f.read()  
    return bytes(s, encoding="utf8")  
  
  
# 定義一個url和實際要執行的函數的對應關係  
list1 = [  
    ("/index/", index),  
    ("/home/", home),  
]  
  
while True:  
    # 等待連接  
    conn, add = sk.accept()  
    data = conn.recv(8096)  # 接收客戶端發來的消息  
    # 從data中取到路徑  
    data = str(data, encoding="utf8")  # 把收到的位元組類型的數據轉換成字元串  
    # 按\r\n分割  
    data1 = data.split("\r\n")[0]  
    url = data1.split()[1]  # url是我們從瀏覽器發過來的消息中分離出的訪問路徑  
    conn.send(b'HTTP/1.1 200 OK\r\n\r\n')  # 因為要遵循HTTP協議,所以回覆的消息也要加狀態行  
    # 根據不同的路徑返回不同內容  
    func = None  # 定義一個保存將要執行的函數名的變數  
    for item in list1:  
        if item[0] == url:  
            func = item[1]  
            break  
    if func:  
        response = func(url)  
    else:  
        response = b"404 not found!"  
  
    # 返回具體的響應消息  
    conn.send(response)  
    conn.close()  
返回具體的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>index</title>
</head>
<body>
<div>這是index頁面</div>
</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>index</title>
</head>
<body>
<div>這是home頁面</div>
</body>
</html>
home.html

 

""" 
根據URL中不同的路徑返回不同的內容--函數進階版 
返回獨立的HTML頁面 
"""  
  
import socket  
  
sk = socket.socket()  
sk.bind(("127.0.0.1", 8080))  # 綁定IP和埠  
sk.listen()  # 監聽  
  
  
# 將返回不同的內容部分封裝成不同的函數  
def index(url):  
    # 讀取index.html頁面的內容  
    with open("index.html", "r", encoding="utf8") as f:  
        s = f.read()  
    # 返回位元組數據  
    return bytes(s, encoding="utf8")  
  
  
def home(url):  
    with open("home.html", "r", encoding="utf8") as f:  
        s = f.read()  
    return bytes(s, encoding="utf8")  
  
  
def timer(url):  
    import time  
    with open("time.html", "r", encoding="utf8") as f:  
        s = f.read()  
        s = s.replace('@@time@@', time.strftime("%Y-%m-%d %H:%M:%S"))  
    return bytes(s, encoding="utf8")  
  
  
# 定義一個url和實際要執行的函數的對應關係  
list1 = [  
    ("/index/", index),  
    ("/home/", home),  
    ("/time/", timer),  
]  
  
while True:  
    # 等待連接  
    conn, add = sk.accept()  
    data = conn.recv(8096)  # 接收客戶端發來的消息  
    # 從data中取到路徑  
    data = str(data, encoding="utf8")  # 把收到的位元組類型的數據轉換成字元串  
    # 按\r\n分割  
    data1 = data.split("\r\n")[0]  
    url = data1.split()[1]  # url是我們從瀏覽器發過來的消息中分離出的訪問路徑  
    conn.send(b'HTTP/1.1 200 OK\r\n\r\n')  # 因為要遵循HTTP協議,所以回覆的消息也要加狀態行  
    # 根據不同的路徑返回不同內容  
    func = None  # 定義一個保存將要執行的函數名的變數  
    for item in list1:  
        if item[0] == url:  
            func = item[1]  
            break  
    if func:  
        response = func(url)  
    else:  
        response = b"404 not found!"  
  
    # 返回具體的響應消息  
    conn.send(response)  
    conn.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部分:

  1. """  
  2. 根據URL中不同的路徑返回不同的內容--函數進階版  
  3. 返回HTML頁面  
  4. 讓網頁動態起來  
  5. wsgiref模塊版  
  6. """   
  7.      
  8. from wsgiref.simple_server import make_server   
  9.      
  10.      
  11. # 將返回不同的內容部分封裝成函數   
  12. def index(url):   
  13.     # 讀取index.html頁面的內容   
  14.     with open("index.html", "r", encoding="utf8") as f:   
  15.         s = f.read()   
  16.     # 返回位元組數據   
  17.     return bytes(s, encoding="utf8")   
  18.      
  19.      
  20. def home(url):   
  21.     with open("home.html", "r", encoding="utf8") as f:   
  22.         s = f.read()   
  23.     return bytes(s, encoding="utf8")   
  24.      
  25.      
  26. def timer(url):   
  27.     import time   
  28.     with open("time.html", "r", encoding="utf8") as f:   
  29.         s = f.read()   
  30.         s = s.replace('@@time@@', time.strftime("%Y-%m-%d %H:%M:%S"))   
  31.     return bytes(s, encoding="utf8")   
  32.      
  33.      
  34. # 定義一個url和實際要執行的函數的對應關係   
  35. list1 = [   
  36.     ("/index/", index),   
  37.     ("/home/", home),   
  38.     ("/time/", timer),   
  39. ]   
  40.      
  41.      
  42. def run_server(environ, start_response):   
  43.     start_response('200 OK', [('Content-Type', 'text/html;charset=utf8'), ])  # 設置HTTP響應的狀態碼和頭信息   
  44.     url = environ['PATH_INFO']  # 取到用戶輸入的url   
  45.     func = None   
  46.     for i in list1:   
  47.         if i[0] == url:   
  48.             func = i[1]   
  49.             break   
  50.     if func:   
  51.         response = func(url)   
  52.     else:   
  53.         response = b"404 not found!"   
  54.     return [response, ]   
  55.      
  56.      
  57. if __name__ == '__main__':   
  58.     httpd = make_server('127.0.0.1', 8090, run_server)   
  59.     print("我在8090等你哦...")   
  60.     httpd.serve_forever()  

jinja2

上面的代碼實現了一個簡單的動態,我完全可以從資料庫中查詢數據,然後去替換我html中的對應內容,然後再發送給瀏覽器完成渲染。 這個過程就相當於HTML模板渲染數據。 本質上就是HTML內容中利用一些特殊的符號來替換要展示的數據。 我這裡用的特殊符號是我定義的,其實模板渲染有個現成的工具: jinja2

下載jinja2:

pip install jinja2
<!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>
    <h1>姓名:{{name}}</h1>
    <h1>愛好:</h1>
    <ul>
        {% for hobby in hobby_list %}
        <li>{{hobby}}</li>
        {% endfor %}
    </ul>
</body>
</html>
index2.html文件

使用jinja2渲染index2.html文件:

  1. from wsgiref.simple_server import make_server  
  2. from jinja2 import Template  
  3.   
  4.   
  5. def index(url):  
  6.     # 讀取HTML文件內容  
  7.     with open("index2.html", "r", encoding="utf8") as f:  
  8.         data = f.read()  
  9.         template = Template(data)   # 生成模板文件  
  10.         ret = template.render({'name': 'alex', 'hobby_list': ['抽煙', '喝酒', '燙頭']})   # 把數據填充到模板中  
  11.     return bytes(ret, encoding="utf8")  
  12.   
  13.   
  14. def home(url):  
  15.     with open("home.html", "r", encoding="utf8") as f:  
  16.         s = f.read()  
  17.     return bytes(s, encoding="utf8")  
  18.   
  19.   
  20. # 定義一個url和實際要執行的函數的對應關係  
  21. list1 = [  
  22.     ("/index/", index),  
  23.     ("/home/", home),  
  24. ]  
  25.   
  26.   
  27. def run_server(environ, start_response):  
  28.     start_response('200 OK', [('Content-Type', 'text/html;charset=utf8'), ])  # 設置HTTP響應的狀態碼和頭信息  
  29.     url = environ['PATH_INFO']  # 取到用戶輸入的url  
  30.     func = None  
  31.     for i in list1:  
  32.         if i[0] == url:  
  33.             func = i[1]  
  34.             break  
  35.     if func:  
  36.         response = func(url)  
  37.     else:  
  38.         response = b"404 not found!"  
  39.     return [response, ]  
  40.   
  41.   
  42. if __name__ == '__main__':  
  43.     httpd = make_server('127.0.0.1', 8090, run_server)  
  44.     print("我在8090等你哦...")  
  45.     httpd.serve_forever()  

現在的數據是我們自己手寫的,那可不可以從資料庫中查詢數據,來填充頁面呢?

使用pymysql連接資料庫:

複製代碼
conn = pymysql.connect(host="127.0.0.1", port=3306, user="root", passwd="xxx", db="xxx", charset="utf8")
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
cursor.execute("select name, age, department_id from userinfo")
user_list = cursor.fetchall()
cursor.close()
conn.close()
複製代碼

創建一個測試的user表:

CREATE TABLE user(
  id int auto_increment PRIMARY KEY,
  name CHAR(10) NOT NULL,
  hobby CHAR(20) NOT NULL
)engine=innodb DEFAULT charset=UTF8;

模板的原理就是字元串替換,我們只要在HTML頁面中遵循jinja2的語法規則寫上,其內部就會按照指定的語法進行相應的替換,從而達到動態的返回內容。

 以下內容留存,一些配置信息修改: 重要

 

模板文件配置:

複製代碼
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, "template")],  # template文件夾位置
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

 

靜態文件配置:

STATIC_URL = '/static/'  # HTML中使用的靜態文件夾首碼
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, "static"),  # 靜態文件存放位置
]

 

剛開始學習時可在配置文件中暫時禁用csrf中間件,方便表單提交測試。

複製代碼
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    # 'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

1. HTTP協議
 
  1. 請求(瀏覽器發送給伺服器的消息-request)
   格式:
    請求方式 URL 協議版本
    k1: v1
    k2: v2
    
    請求數據(請求體)
  
  2. 響應(伺服器返回給瀏覽器的消息-response)
   格式:
    協議版本 狀態碼 狀態描述符
    k1: v1
    k2: v2
    
    響應體(HTML)


 2. web框架
  本質: socket服務端
  
  功能:
   a. socket收發消息
   b. URL和函數的對應關係,根據不同的URL執行不同的函數,返回函數的結果
   c. 讀取HTML文件,進行了一個字元替換(模板渲染)
  
  分類:
   Django flask tornado
   完成了a,b,c三個功能的  ——》 tornado
   完成了b,c 兩個功能     ——》 Django
   完成了b 一個功能       ——》 flask
   
  另一種分類:
   1. Django  大而全
   2. 其他   短小精悍
 3. 安裝Django
  1. pycharm
   file settings project 點加號 輸入django 選擇版本 下載
   
  2. 命令行
   pip install django==1.11.15
   
 4. 創建Django項目
  1. 命令行

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 第1章 Rsync基本概述 1.1 什麼是Rsync rsync是一款開源,快速,多功能的可實現增量的本地或遠程的數據鏡像同步備份的優秀工具。適用於多個平臺。從軟體名稱可以看出來是遠程同步的意思(remote sync)可實現全量備份與增量備份,因此非常適合用於架構集中式備份或異地備份等應用。 1. ...
  • 首先聲明,我的文章不配圖,就靠文字描述,然後自己體會,摸著石頭體驗吧! 從今天開始玩Linux,Ubuntu16.04據說是比較穩定的,界面友好,類似與Windows界面,也有Linux的命令終端,用起來有一種想要起飛的感覺,O(∩_∩)O哈哈~ 1、首先說安裝步驟,就是怎麼將Ubuntu16.04 ...
  • Windows 下安裝drozer(Windows 10),連接手機(紅米note4X) 首先下載drozer(http://mwr.to/drozer)。 紅米手機開發者模式 遇到第一個問題,紅米手機開發者模式。好久不用這個了,發現找不到。網上搜索一波, 在設置-我的設備-全部參數,位置,點擊MI ...
  • Sharding-Proxy是Sharding-Sphere的第二個產品。它定位為透明化的資料庫代理端,提供封裝了資料庫二進位協議的服務端版本,用於完成對異構語言的支持。目前先提供MySQL版本,它可以使用任何相容MySQL協議的訪問客戶端(如:MySQL Command Client, MySQL... ...
  • linux下,資料庫意外關閉,可能導致連接不了。可能報錯: 解決方法: 第一步:看監聽起來沒有 或者 第二步:如果沒有,則開啟 第三步:再次查看: 第四步:登錄資料庫 第五步:以管理員許可權連接 第六步:啟動資料庫 ...
  • 1.utf8與utf8mb4(utf8 most bytes 4) MySQL 5.5.3之後增加了utfmb4字元編碼 支持BMP(Basic Multilingual Plane,基本多文種平面)和補充字元 最多使用四個位元組存儲字元 utf8mb4是utf8的超集並完全相容utf8,能夠用四個字 ...
  • MySQL實現排名並查詢指定用戶排名功能,併列排名功能 表結構: CREATE TABLE test.testsort ( id int(11) NOT NULL AUTO_INCREMENT, uid int(11) DEFAULT 0 COMMENT '用戶id', score decimal( ...
  • 1,索引 2.exists 代替 in 3.SQL優化 4、觸發器[表上創建的] 5、存儲過程【創建在資料庫上的】 6、資料庫引擎ENGINE【MYISAM,INNODB】 7、MySQL如何修改密碼 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...