從 AJAX 到 axios:前端與服務器通信實戰指南

直到現在我們小寧已經更新了44作品了,其中和大家介紹了Python入門基礎、Fast API框架、SQLite數據庫,以及前端的知識都已經學習完了,總的來說現在前端、后端、數據庫已經都學習了,那大家是否有這樣的疑問,前端后端到底應該怎么聯系起來使用呢?

在現代 Web 開發中,網頁不再是靜態的信息展示板,而是能與服務器實時交互的動態應用。實現這一功能的核心技術就是 AJAX,而 axios 則是簡化 AJAX 操作的利器。本文從基礎概念到實戰案例,帶你掌握前端與服務器通信的全流程。

一、認識 AJAX:讓數據 “動” 起來

1. 什么是 AJAX?

AJAX(Asynchronous JavaScript and XML)是一種通過瀏覽器的?XMLHttpRequest?對象與服務器異步通信的技術。它能讓網頁在不刷新的情況下,向服務器請求數據并更新頁面內容。

例如,當你在網頁上點擊 “查詢省份” 按鈕時,瀏覽器通過 AJAX 向服務器發送請求,服務器返回省份列表數據,前端直接將數據展示在頁面上,整個過程無需刷新頁面。

2. 為什么需要 AJAX?

傳統網頁的數據是固定寫在代碼中的,無法實時更新。有了 AJAX,數據可以從服務器動態獲取,讓頁面內容 “活” 起來。比如:實時顯示最新的省份 / 城市列表、用戶登錄狀態驗證等。

3. 為什么選擇 axios?

AJAX 底層依賴?XMLHttpRequest?對象,但語法繁瑣。axios 是一個基于 Promise 的 HTTP 客戶端,語法簡潔,且在 Vue 等框架中被廣泛使用,能讓我們更專注于業務邏輯而非底層通信細節。

二、URL:定位服務器資源的 “地址”

要與服務器通信,首先需要知道資源的位置 ——URL(統一資源定位符)。

1. URL 的核心組成

一個完整的 URL 包含三個關鍵部分:

  • 協議:如?http://,規定瀏覽器與服務器的通信規則;
  • 域名 / IP:如?127.0.0.1:8000,標記服務器在網絡中的位置;
  • 資源路徑:如?/api/province,指定服務器上具體資源的位置。

例如,http://127.0.0.1:8000/api/province?表示:通過 HTTP 協議,訪問本地服務器(127.0.0.1:8000)上的省份列表資源。

2. axios 中攜帶查詢參數

在 axios 中,通過?params?選項設置查詢參數,無需手動拼接 URL:

// 獲取遼寧省的城市列表
axios({url: 'http://127.0.0.1:8000/api/city',params: {pname: '遼寧省' // 參數名與服務器要求一致(課件中服務器約定參數名為pname)}
}).then(result => {// 服務器返回的數據格式為 { list: [城市1, 城市2, ...] }console.log('遼寧省城市列表:', result.data.list); // 渲染到頁面:將城市列表轉為li標簽document.querySelector('ul').innerHTML = result.data.list.map(city => `<li>${city}</li>`).join('');
});

三、請求方法和常見報錯:與服務器的 “交互方式”

HTTP 協議定義了多種請求方法,用于表示對服務器資源的操作。常用方法如下:

請求方法作用示例
GET獲取資源(如查詢數據)查詢省份列表
POST提交數據(如注冊、登錄)用戶注冊
PUT全量更新資源修改用戶所有信息
DELETE刪除資源刪除一條記錄

HTTP 常見響應狀態碼(錯誤碼)說明

狀態碼類別含義說明常見場景示例
200成功請求成功,服務器正常返回數據登錄成功、查詢數據成功
400客戶端錯誤請求參數錯誤或格式不正確用戶名不符合規則(如長度不足)
401客戶端錯誤未授權,需要驗證身份(如登錄失效)密碼錯誤、未登錄訪問需要權限的資源
404客戶端錯誤請求的資源不存在訪問了錯誤的 URL(如?/api/xxx?拼寫錯誤)
500服務器錯誤服務器內部出錯,無法處理請求服務器代碼報錯、數據庫連接失敗
403客戶端錯誤服務器拒絕請求(如權限不足)普通用戶嘗試刪除管理員數據
408客戶端錯誤請求超時網絡延遲導致服務器未及時收到請求
503服務器錯誤服務器暫時不可用(如維護中)服務器負載過高、正在重啟

四、綜合案例

1、axios的使用步驟

①引入axios.js文件到自己的網頁中:axios 在線引入地址(復制直接使用)

<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/1.6.2/axios.min.js"></script>

明確axios函數的使?語法

綜合語句1:
axios({// 配置項url: '目標地址',method: '請求方法', // 默認為 getparams: {}, // GET 參數data: {}    // POST 參數
})
.then(result => {// 成功回調:處理服務器返回的數據
})
.catch(error => {// 失敗回調:處理錯誤信息
});綜合語句2:
axios.請求方法(url:'目標地址',{參數名1:值1;.......
}).then(result => {// 成功回調:處理服務器返回的數據
})
.catch(error => {// 失敗回調:處理錯誤信息
});

2、綜合案例代碼

?province_API.py:這里有后續網頁對應的API接口

from fastapi import FastAPI
# 瀏覽器出于安全考慮,默認會阻止跨域請求(例如前端運行在 http://localhost:3000,
# 而 API 服務在 http://localhost:8000),這時就需要后端設置 CORS 來允許跨域訪問。
from fastapi.middleware.cors import CORSMiddleware
# 用于創建數據庫引擎,常用于同步數據庫連接
from sqlalchemy import create_engine,Column,Integer,String
# 用于創建數據庫會話,用于執行數據庫操作
from sqlalchemy.orm import sessionmaker, declarative_base# 創建FastAPI應用
app = FastAPI()# 添加CORS中間件,允許跨域傳輸
app.add_middleware(CORSMiddleware,allow_origins=["*"],  # 允許所有源allow_credentials=True,  # 是否允許發送 Cookieallow_methods=["*"],  # 允許所有HTTP方法allow_headers=["*"],  # 允許所有HTTP頭部
)
# 定義數據庫連接URL
DATABASE_URL = "sqlite:///province.db"
# 創建數據庫引擎,設置連接參數以允許在多線程環境中使用(地址)
engine = create_engine(DATABASE_URL,connect_args={"check_same_thread": False})
# 創建會話,綁定數據庫引擎
SessionLocal = sessionmaker(bind=engine)
# 創建基類
Base = declarative_base()
# 創建數據庫表結構(可以創建數據庫表結構)
class Province(Base):__tablename__ = "province"code = Column(String)id = Column(Integer, primary_key=True, index=True)name = Column(String, unique=True, index=True)
# 執行創建數據庫表結構
Base.metadata.create_all(bind = engine)@app.get("/api/all_province")
def get_all_provinces():"""獲取所有省份列表返回格式與前端期望的格式一致,包含list屬性"""db = SessionLocal()try:provinces = db.query(Province).all()province_list = [province.name for province in provinces]return {"list": province_list}finally:db.close()@app.get("/api/find_province")
def find_province(name: str):"""根據名稱查詢省份返回格式與前端期望的格式一致,包含list屬性"""db = SessionLocal()try:find_province = db.query(Province).filter(Province.name == name).first()if find_province:return find_province.namereturn "未找到該省份"finally:db.close()# 實現城市查詢API接口
@app.get("/api/city")
def get_cities(pname: str = None):"""根據省份名稱獲取城市列表參數:- pname: 省份名稱"""# 這里簡化處理,實際應該查詢數據庫中的城市數據# 為演示目的,返回一些示例城市cities = {"遼寧省": ["沈陽市", "?連市", "鞍?市", "撫順市", "本溪市"],"上海": ["上海市"],"?東省": ["?州市", "深圳市", "珠海市", "汕頭市", "佛?市"],"北京": ["北京", "東城", "西城", "朝陽", "海淀", "豐臺", "石景山", "門頭溝", "房山", "通州", "順義", "昌平"],"天津": ["天津", "和平", "河北", "河東", "河西", "南開", "河北", "和平", "寧河", "東麗", "西青", "津南", "北辰"],}if pname and pname in cities:return {"list": cities[pname]}return {"list": []}
# 實現地區查詢API接口
@app.get("/api/area")
def get_areas(cname: str = None):"""根據省份和城市名稱獲取地區列表參數:- pname: 省份名稱- cname: 城市名稱"""# 這里簡化處理,實際應該查詢數據庫中的地區數據# 為演示目的,返回一些示例地區areas = {"北京市": ["東城區", "西城區", "朝陽區", "海淀區", "豐臺區", "石景山區"],"上海市": ["黃浦區", "徐匯區", "長寧區", "靜安區", "普陀區", "虹口區"],"廣州市": ["越秀區", "荔灣區", "海珠區", "天河區", "白云區", "黃埔區"],"深圳市": ["福田區", "羅湖區", "南山區", "寶安區", "龍崗區", "鹽田區"]}if cname and cname in areas:return {"list": areas[cname]}return {"list": []}if __name__ == "__main__":import uvicornuvicorn.run(app, host="127.0.0.1", port=8080)

data.py:主要用于創建數據庫,插入數據庫的省份數據

import sqlite3
# 創建數據庫連接
conn = sqlite3.connect('province.db')
# 創建數據庫游標:游標能夠對數據庫進行操作
cursor = conn.cursor()
# 創建表
sql = '''
CREATE TABLE IF NOT EXISTS province (id INTEGER PRIMARY KEY,name TEXT NOT NULL,code TEXT NOT NULL
)'''
cursor.execute(sql)
sql = '''
insert into province(name,code)values
('北京', '110000'),
('天津', '120000'),
('河北', '130000'),
('??', '140000'),
('內蒙古', '150000'),
('遼寧', '210000'),
('吉林', '220000'),
('??江', '230000'),
('上海', '310000'),
('江蘇', '320000'),
('浙江', '330000'),
('安徽', '340000'),
('福建', '350000'),
('江?', '360000')
'''
cursor.execute(sql)
conn.commit()
conn.close()

?all_province.html:這個頁面主要是對應?province_API里面的第一個接口,使用get的請求方式,不帶參數來獲取數據庫的所有省份信息

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>所有的省份信息</title>
</head>
<body><h1>這里是所有的省份信息</h1><p id="all_province"></p><script src="https://cdnjs.cloudflare.com/ajax/libs/axios/1.6.2/axios.min.js"></script><script>axios({url: 'http://127.0.0.1:8080/api/all_province'}).then(result => {// 對服務器返回的數據做后續處理console.log(result)console.log(result.data)console.log(result.data.list)let all_province = document.getElementById('all_province')all_province.innerHTML = result.data.list.join('<br/>')})</script><p></p>
</body>
</html>

?

find_city.html:這個頁面主要是對應?province_API里面的第二個接口,使用post的請求方式,帶查詢城市名稱參數來獲取地區信息
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>顯示城市的各個區</title>
</head>
<body><h1>顯示城市的各個區</h1>城市:<input type="text" id="input" placeholder="請輸入你要查找的城市"><button id = "btn">查找</button><h2>以下是查找的結果:</h2>省份:<p id="sf"></p>區:<p id="city"></p><script src="https://cdnjs.cloudflare.com/ajax/libs/axios/1.6.2/axios.min.js"></script><script>let input = document.getElementById('input');let btn = document.getElementById('btn');let sf = document.getElementById('sf');let city = document.getElementById('city');btn.addEventListener('click', function () {if (input.value) {axios({url: 'http://127.0.0.1:8080/api/city',params: {pname: input.value}}).then(result => {// 對服務器返回的數據做后續處理// console.log(result)// console.log(result.data)console.log(result.data.list)if (result.data.list.length != 0){sf.innerHTML = input.valuecity.innerHTML = result.data.list.join('<br/>')}else {sf.innerHTML = '沒有找到該城市'}})}})</script>
</body>
</html>

?

find_area.html:這個頁面主要是對應?province_API里面的第三個接口,使用post的請求方式,帶查詢城市名稱參數來獲取地區信息
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>查找地區列表</title><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>案例_地區查詢</title>
</head>
<body><h1>顯示城市的各個區</h1>城市:<input type="text" id="input" placeholder="請輸入你要查找的城市"><button id = "btn">查找</button><h2>以下是查找的結果:</h2>城市:<p id="sf"></p>區:<p id="city"></p><script src="https://cdnjs.cloudflare.com/ajax/libs/axios/1.6.2/axios.min.js"></script><script>const input = document.getElementById('input');const btn = document.getElementById('btn');const sf = document.getElementById('sf');const city = document.getElementById('city');btn.addEventListener('click', function () {if (input.value) {axios({url: 'http://127.0.0.1:8080/api/area',params: {cname: input.value}}).then(result => {// 對服務器返回的數據做后續處理// console.log(result)// console.log(result.data)console.log(result.data.list)if (result.data.list.length != 0){sf.innerHTML = input.valuecity.innerHTML = result.data.list.join('\n')}else {sf.innerHTML = '沒有找到該城市'}})}})</script>
</body>
</html>

find_province.html:這個頁面主要是對應?province_API里面的第四個接口,使用post的請求方式,帶查詢數據庫中是否存在該城市
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>查找城市是否存在</title>
</head>
<body><input type="text" id="input"><button id="btn">查找</button><p id="find_province"></p><script src="https://cdnjs.cloudflare.com/ajax/libs/axios/1.6.2/axios.min.js"></script><script>let input = document.getElementById('input');let btn = document.getElementById('btn');let find_province = document.getElementById('find_province');btn.addEventListener('click', function () {if (input.value) {axios({url: 'http://127.0.0.1:8080/api/find_province',params: {name: input.value}}).then(result => {// 對服務器返回的數據做后續處理console.log(result)console.log(result.data)find_province.innerText = result.data})}})</script>
</body>
</html>

五、綜合案例 2:用戶登錄(結合 form-serialize)

需求:實現用戶登錄功能,包含表單驗證、數據提交和結果提示,并使用?form-serialize?插件簡化表單數據收集。

1. form-serialize 插件介紹

1. 我們前?收集表單元素的值,是?個個標簽獲取的
2. 如果?套表單?有很多很多表單元素,如何?次性快速收集出來呢?
3. 使? form-serialize 插件提供的 serialize 函數就可以辦到
4. form-serialize 插件語法:
? ?
  • 引入插件:<script src="https://unpkg.com/form-serialize@0.7.2/form-serialize.min.js"></script>
  • 調用?serialize?函數:serialize(表單元素, { hash: true, empty: true })hash: true?返回對象,empty: true?包含空值)。
參數1:要獲取的 form 表單標簽對象(要求表單元素需要有 name 屬性-?來作為收集的
數據中屬性名)
參數2:配置對象
????????hash:
????????????????true - 收集出來的是?個 JS 對象結構
????????????????false - 收集出來的是?個查詢字符串格式
????????empty:
????????????????true - 收集空值
????????????????false - 不收集空值
5. 需求:收集登錄表單??戶名和密碼
   <!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.0"><title>form-serialize插件使?</title></head><body><form action="javascript:;" class="example-form"><input type="text" name="username"><br><input type="text" name="password"><br><input type="button" class="btn" value="提交"></form><!--/2. 使?serialize函數,快速收集表單元素的值參數1:要獲取哪個表單的數據表單元素設置name屬性,值會作為對象的屬性名建議name屬性的值,最好和接??檔參數名?致參數2:配置對象hash 設置獲取數據結構- true:JS對象(推薦)?般請求體?提交給服務器- false: 查詢字符串empty 設置是否獲取空值- true: 獲取空值(推薦)數據結構和標簽結構?致- false:不獲取空值/--><!-- 引入 serialize.js 插件 --><script src="https://unpkg.com/form-serialize@0.7.2/form-serialize.min.js"></script><script>document.querySelector('.btn').addEventListener('click', () => {const form = document.querySelector('.example-form');const data = serialize(form, { hash: true, empty: true });// const data = serialize(form, { hash: false, empty: true });// const data = serialize(form, { hash: true, empty: false });console.log(data);});</script></body></html>


?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/86757.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/86757.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/86757.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Pycatia二次開發基礎代碼解析:面屬性控制、視圖定向與特征統計的工業級實現

本文將以專業視角深入解析CATIA二次開發中的三個核心類方法&#xff0c;通過詳細分析代碼實現揭示其在工業設計中的實際應用價值。全文將嚴格圍繞提供的代碼展開&#xff0c;不做任何修改或補充。 一、面屬性控制&#xff1a;精確可視化表達技術 方法功能解析 color_and_laye…

bmc TrueSight 監控 Oracle 11g 配置

bmc TrueSight 監控 Oracle配置 文章目錄 bmc TrueSight 監控 Oracle配置1.將pat加入oinstall和dba組2.創建監控的表空間和臨時表空間并告知表空間名稱3.將oracle相關系統環境變量加入到監控pat賬戶的.profile或.bash_profile文件4.登陸Apollo監控web頁面&#xff0c;設置基礎架…

css實現高度可變、上下邊框是漸變色、左右邊框是純色的div容器

效果圖&#xff1a; div容器&#xff1a; <div className{styles.container}><div className{styles.content}><div className{styles.inner}><!-- 內容部分 --></div></div> </div> css&#xff1a; .container {float: left;w…

python二維碼識別

pyzbar 識別QR二維碼 from PIL import Image from pyzbar.pyzbar import decode# 打開圖像文件 image_path qr01.jpg # 替換為你的圖像路徑 image Image.open(image_path)# 解碼圖像中的二維碼 decoded_objects decode(image)# 輸出識別結果 for obj in decoded_objects:p…

ZYNQ EMMC/FLASH/SD卡深度性能評測與創新實踐

深入探索ZYNQ存儲子系統性能,揭示硬件加速下的存儲優化之道 一、存儲性能為何如此重要? 在基于Xilinx ZYNQ SoC的嵌入式系統中,EMMC、QSPI FLASH和SD卡作為核心存儲介質,直接影響系統啟動時間、數據吞吐量和用戶體驗。傳統測試方法往往局限于簡單讀寫速度測試,缺乏對真實…

html制作一個簡單的表單

<!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><title>表單輸入練習</title><style></style> </head><body style"background-color: pink;"><div><h2>…

差分對的等長等距

差分對的等長等距: 差分對中兩個單端信號的延時差會導致接收端信號的錯位&#xff0c;引起差分信號的畸變&#xff0c;同時會產生共模噪聲導致接收端差分信號抖動增加。因此差分對設計的一個基本要求就是要盡量保持差分對兩條單端線延時相等。 圖8-27顯示了差分對中兩條單端線…

SQL 子查詢全位置解析:可編寫子查詢的 7 大子句

&#x1f50d; SQL 子查詢全位置解析&#xff1a;可編寫子查詢的 7 大子句 子查詢可以出現在 SQL 語句的多個關鍵位置&#xff0c;不同位置的子查詢具有獨特的行為和限制。以下是系統化總結&#xff1a; &#x1f4cc; 1. WHERE 子句&#xff08;最常用&#xff09; SELECT 列…

C#高級:Winform桌面開發中DataGridView的詳解(新)

一、數據填充&#xff08;反射&#xff09; 1.封裝 /// <summary> /// 渲染DataGridView /// </summary> /// <param name"dataGridView">被渲染控件</param> /// <param name"list">數據集</param> /// <param …

人臉活體識別2:Pytorch實現人臉眨眼 張嘴 點頭 搖頭識別(含訓練代碼和數據集)

人臉活體識別2&#xff1a;Pytorch實現人臉眨眼 張嘴 點頭 搖頭識別(含訓練代碼和數據集) 目錄 人臉活體識別2&#xff1a;Pytorch實現人臉眨眼 張嘴 點頭 搖頭識別(含訓練代碼和數據集) 1. 前言 2.人臉活體識別方法 &#xff08;1&#xff09;基于人臉動作的檢測?? &a…

Webpack 自定義插件開發指南:構建流程詳解與實戰開發全攻略

一. webpack打包流程 開發 Webpack 插件的第一步&#xff0c;就是明確&#xff1a;我的插件要接入 Webpack 構建流程的哪個階段&#xff0c;解決什么問題。 了解流程之前首先要了解插件的兩個核心概念&#xff1a;compiler&#xff0c;compilation 1. compiler&#xff1a;全局…

本地部署Dify+Ragflow及使用(一)

概念說明 RAGflow&#xff1a; 吃透知識&#xff1a;將企業文檔&#xff08;如技術白皮書&#xff09;解析為結構化知識片段。精準檢索&#xff1a;當用戶提問時&#xff0c;從知識庫中召回最相關內容。 模型供應商&#xff1a; 提供大腦&#xff1a;為 Dify 提供生成答案的模…

2025.06.24【R語言】|clusterProfiler安裝與常見報錯FAQ全解

文章目錄 一、clusterProfiler安裝方法1. Bioconductor官方推薦2. Conda安裝&#xff08;個人推薦 適合服務器/依賴復雜環境&#xff09;3. 檢查安裝 二、常見依賴包安裝三、常見報錯與解決方案1. 報錯&#xff1a;could not find function "bitr"2. 報錯&#xff1a…

【轉】PostgreSql的鏡像地址

docker.io/postgres 項目中國可用鏡像列表 | 高速可靠的 Docker 鏡像資源 docker.io/postgrest/postgrest:v12.2.8 linux/amd64 docker.io17.34MB2025-04-04 13:14 346 docker.io/postgrest/postgrest:v12.2.12 linux/amd64 docker.io17.38MB2025-05-27 22:02 79 docker.io…

爬蟲005----Selenium框架

在總結爬蟲 &#x1f577; 框架之前&#xff0c;先總結一下selenium框架&#xff0c;也可以說是selenium庫&#xff0c;在自動化測試中是老生常談了&#xff08;長時間??不用&#xff0c;已經忘記了&#xff0c;實際測試工作中做UI自動化的也很少了&#xff0c;上次搞UI自動化…

記一次 Kafka 磁盤被寫滿的排查經歷

開篇扯犢子 今天踏進辦公聽到不是同事的早安&#xff0c;而是“有一個好消息&#xff0c;一個壞消息&#xff0c;你想聽哪個&#xff1f;” 我一愣&#xff0c;心想“大早上&#xff0c;就要玩刺激的嗎&#xff1f;” 但是還是淡定的回復說“無所謂&#xff0c;哥什么場面沒見…

python多線程:各線程的輸出在控制臺中同一行原因分析

代碼例子 import threading import timedef error_worker():print("子線程開始")time.sleep(1)raise Exception("子線程出錯了&#xff01;")t threading.Thread(targeterror_worker) t.start()print("主線程繼續執行&#xff0c;不受子線程異常影響…

Promptify與ReActAgent

一、Promptify 定位&#xff1a;NLP 任務的「自動化流水線」 1. 解決什么問題&#xff1f; 傳統 LLM 應用開發痛點&#xff1a; 反復調試&#xff1a;需手工編寫/調整 prompt 格式&#xff08;如調整分隔符、示例數量&#xff09;兼容性差&#xff1a;不同模型需重寫適配代碼…

如何將視頻從 iPhone 發送到 Android 設備

如果您想將視頻從 iPhone 發送到 Android 設備&#xff0c;尤其是視頻尺寸較大時&#xff0c;您需要一種高效的傳輸方法。本文將為您提供 7 種實用方法&#xff0c;讓您輕松發送大型視頻文件或短視頻片段&#xff0c;并且不會損失視頻質量。 第 1 部分&#xff1a;如何通過 iRe…

Stable Diffusion入門-ControlNet 深入理解 第四課:風格遷移與重繪控制模型——讓AI也有“藝術天賦”!

大家好&#xff0c;歡迎回到 Stable Diffusion入門-ControlNet 深入理解 系列的第四課&#xff01; 如果你還沒有看過上一課&#xff0c;趕緊補課哦&#xff1a;Stable Diffusion入門-ControlNet 深入理解 第三課。 上一課我們講解了 ControlNet 結構類模型&#xff0c;今天我…