昨日了解完Flask的安裝至頁面跳轉、動態生成等內容後,今天我們要更深入介紹Flask的請求和表單製作!
在學習請求前,我們要先了解HTTP方法:
HTTP(Hypertext Transfer Protocol),它是一種用於在網際網路上傳輸資訊的標準協議。而HTTP協議定義了一組不同的方法(HTTP Methods),這些方法允許客戶端和伺服器之間的通信。
當談到HTTP方法時,通常有四個最常用的方法,它們分別是:
這四個方法是HTTP中最常見且最廣泛使用的,它們使客戶端和伺服器能夠執行基本的檢索、創建、更新和刪除操作,這些操作在網頁應用程序和API中非常重要。不同的HTTP方法允許不同的交互方式,並支持多元的應用。
在Flask中,我們可以這樣寫:
@app.route("/api/getPage",methods=["GET"])
def getData():
datas = json.load(open("flask/static/json/page.json",mode="r",encoding="utf-8"))
return datas
使用上述的程式碼,並開啟瀏覽器中的DevTools,便可以看到我們從後端獲取的資料。
若您想要在您的網站中使用這個GET的方法時,不妨看看下方的範例:
有關jQuery之詳情可參考 ⇒ 【Day12】讓網頁動起來(2)元老級插件jQuery!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Article</title>
<script src="https://code.jquery.com/jquery-3.6.1.js" integrity="sha256-3zlB5s2uwoUzrXK3BT7AX3FyvojsraNFxCc2vC/7pNI=" crossorigin="anonymous"></script>
</head>
<body>
</body>
</html>
@app.route("/article")
def article():
return render_template("article.html")
這裡簡單介紹一下路由(route),其實便是兩個節點間通訊的最佳路徑。更多與路由相關的資訊、運作方法…等,本篇便不詳細介紹,若您對此深感興趣,歡迎自行上網查詢喔!
ajax()
函式:先前在介紹jQuery時,我們便有大略提及AJAX(Asynchronous JavaScript and XML),現在終於使用到了,便順帶介紹一下ajax()
函式的用法:
$.ajax() 方法
:在 jQuery 中,您可以使用 $.ajax()
方法來執行 AJAX 請求。這個方法允許您向伺服器發送不同類型的 HTTP 請求,如 GET、POST、PUT、DELETE 等。.done()
、.fail()
和 .always()
方法處理 AJAX 請求的回應。.done()
用於處理成功的回應,.fail()
用於處理錯誤,而 .always()
用於處理無論成功或失敗都應執行的程式碼。
以下是一個簡單的示例,演示如何使用 jQuery 的 $.ajax()
方法發送一個 GET 請求:
$.ajax({
url: 'https://api.example.com/data',
method: 'GET',
dataType: 'json',
})
.done(function(response) {
// 成功處理回應
console.log('成功:', response);
})
.fail(function(jqXHR, textStatus, errorThrown) {
// 處理錯誤
console.error('錯誤:', errorThrown);
})
.always(function() {
// 無論成功或失敗,都執行這個程式碼
console.log('完成');
});
我們可以把我們想要取得資料的網頁網址給填進去:
接著在瀏覽器中打開DevTools,便可以看到我們成功獲取資料了!
也可以嘗試使用程式碼較少的寫法,結果會是相同的:
$.ajax({
url: '/api/getPage',
method: 'GET',
dataType: 'json',
success:(response)=>{
console.log(response);
}
})
取得資料後,我們就可以做出生成的動作了:
$.ajax({
url: '/api/getPage',
method: 'GET',
dataType: 'json',
success:(response)=>{
// todo del
console.log(response);
const app = $(".app");
for (let i=0 ;i<response["page"].length;i++) {
// todo del
console.log(response["page"][i]["title"]);
app.append(`<li><a href="/${response["page"][i]["title"]}">${response["page"][i]["title"]}</a></li>`)
}
}
})
如此一來,便可以輕鬆做好連結跳轉頁面的功能了!
而跟Get相反的方法就是Post方法了。
Post 貼文,顧名思義就是把資料傳到後端去處理,而此方法能夠做到以下功能:
我們可以為網頁添增幾個輸入框,供使用者做輸入資料的動作:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Form</title>
</head>
<body>
<form action="/api/postData" method="POST">
帳號:
<input name="account" type="text">
密碼:
<input name="password" type="password">
<input type="submit" value="submit">
</form>
</body>
</html>
在HTML文本中,製作表單需要使用到 <form>
的標籤:
在<form>
標籤內我們需要填入 action
和 method
。action
,便是當我們送出表單後,要執行何種程式的結果,而method
則是要以甚麼方式操作執行。
同樣為其串上router:
@app.route("/form")
def form():
return render_template("form.html")
接下來,在撰寫post的function前,我們要先引入名為request的插件:
Flask Code:
@app.route("/api/postData",methods=["POST"])
def postData():
account = request.form.get("account")
password = request.form.get("password")
print(account)
print(password)
return f'account: {account}<br>password: {password}'
我們可以透過print去輸出我們的結果,去看看前端的資料是否有正確地被傳到後端。
輸出結果如上:
當然,也可以回傳至其他網頁:
@app.route("/api/postData",methods=["POST"])
def postData():
account = request.form.get("account")
password = request.form.get("password")
return render_template("success.html",account=account)
或者使用另一個方法:
這個方法中,我們要創建一個 success的頁面 和一個 /success
的router。
@app.route("/success")
def success():
return render_template("success.html")
而後在 postData()
的router內修改return(回傳)的值:
@app.route("/api/postData",methods=["POST"])
def postData():
account = request.form.get("account")
password = request.form.get("password")
return redirect("/success")
然而,這種方法,會發現我們的資料不見了,這是因為使用 redirect()
沒辦法像 render_template()
一樣,直接對傳入值做處理。
我們可以採取以下兩種方式在網頁之中傳遞值:
url_for()
:@app.route("/api/postData",methods=["POST"])
def postData():
account = request.form.get("account")
password = request.form.get("password")
return redirect(url_for("success", account=account,password=password))
並從網址中取值:
@app.route("/success")
def success():
account = request.args.get('account')
return render_template("success.html",account=account)
但是,使用這種方式同樣會出現尷尬的小問題 ── 我們的密碼將會被一絲不掛地顯現出來,超級不安全!所以我們會使用第二種方式:
app = Flask(__name__,template_folder="templates")
app.config['SECRET_KEY'] = os.urandom(24)
修改 postData()
:
我們可以透過 session[”索引值”]
來新增或修改值。
順帶一提,session[”索引值”] = False
便是刪除session的意思。
@app.route("/api/postData",methods=["POST"])
def postData():
account = request.form.get("account")
password = request.form.get("password")
session["account"] = account
session["password"] = password
return redirect(url_for("success"))
在 success()
中讀取session:
讀取session是使用 session.get(”索引值”)
語法去取值的:
@app.route("/success")
def success():
account = session.get("account")
return render_template("success.html",account=account)
這樣就完成了。
使用這個方法,我們可以做到各式種類繁多的應用。ex.登入系統…等。
當我們登入系統時,程式去資料庫核對資料是否正確,然後回傳正確的網頁出來:
正確的話則A,不正確的話則B…,反正只要登入後將狀態用session存著,每次進入此網站時便不用重新登入。
@app.route("/api/postData",methods=["POST"])
def postData():
account = request.form.get("account")
password = request.form.get("password")
if 資料正確:
一些處理...
return 正確的網頁
else:
一些處理...
return 重新登入
然而,這部分又是一個大坑了,若您想要了解這方面的資訊,不妨自行上網查詢,關鍵字如下:
python sql
python flask login system
、python flask session
。回歸正題,使用post方法,我們也可以把表單存進資料庫中。
這裡我將會介紹使用JSON存檔的方式:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Question Form</title>
</head>
<body>
<form action="/api/updateForm" method="POST">
你的名字:
<input type="text" name="name" required>
你的年齡:
<input type="text" name="age" required>
你的身高:
<input type="number" name="height" required>
<input type="submit" value="submit">
</form>
</body>
</html>
順帶一提,上方的程式碼中,我添加了許多required
,意思即為必填。
若您在該格未填寫,送出表單時,便會出現以下的結果:
@app.route("/question")
def question():
return render_template("question.html")
使用剛才的方式讀取表單內容:
@app.route("/api/updateForm",methods=["POST"])
def updateForm():
account = request.form.get("name")
age = request.form.get("age")
height = request.form.get("height")
return "<h1>上傳完成</h1>"
在執行這個操作前,我們會使用到先前引入過的JSON模組:
而後創建輸出資料夾和檔案:
當我們要將資料寫入時,我們便需要讀取現有的資料,並把新的資料疊上去。
我們可以這麼撰寫:
@app.route("/api/updateForm",methods=["POST"])
def updateForm():
account = request.form.get("name")
age = request.form.get("age")
height = request.form.get("height")
# 讀取舊資料
with open("flask/static/post/question.json", "r",encoding="utf-8") as json_file:
existing_data = json.load(json_file)
# 打包新資料
new = {
"account":account,
"age":age,
"height":height
}
# 新增
existing_data["data"].append(new)
# 上傳
with open("flask/static/post/question.json", "w",encoding="utf-8") as json_file:
json.dump(existing_data, json_file)
return "<h1>上傳完成</h1>"
輸出結果以上,這便是使用JSON將資料存進資料庫的模樣。
以上,便是今天的Flask請求 & 表單教學,今天的內容偏多,並且較複雜 ── 但這些在網頁應用上是非常廣泛且實用的,可以說是網頁工程師都必備的技能之一!然而,登入系統是個大坑,有興趣的話,除了上網查詢資料,自行摸索、反覆練習也是很重要的喔!