--- title: flask初學 tags: 網站後端開發 --- # Flask 網站後端開發 ## 網址 * 通訊協定://主機名稱:埠號/路徑?要求字串 * 通訊協定(Protocol) * 主機名稱(Hostname) * 埠號(Port) * 路徑(Path) * 要求字串(Query String) * 例如:https://google.com/ * 通訊協定:https * 主機名稱:google.com * 埠號:https預設443 * 路徑:/ * 要求字串:無 * 例如:https://www.google.com/search?q=test * 通訊協定:https * 主機名稱:www.google.com * 埠號:https預設443 * 路徑:/search * 要求字串:q=test * 例如:https://hackmd.io/yYkJ3IbsSWeb-wrjPPj2Yw?view(此網站之url) * 通訊協定:https * 主機名稱:hackmd.io * 埠號:https預設443 * 路徑:/yYkJ3IbsSWeb-wrjPPj2Yw * 要求字串:view * 例如:http://127.0.0.1:5000/ * 通訊協定:http * 主機名稱:127.0.0.1(本機端IP位址) * 埠號:自訂5000 * 路徑:/ * 要求字串:無 ### 網址運作方式 * 瀏覽器前端 * 根據通訊協定、主機名稱、埠號連線到網路上的伺服器 * 伺服器 * 根據路徑、要求字串,決定要採取的動作,並回應給前端 ### 後端程式與網路環境設置,決定網站網址 * 通訊協定:透過後端以及網路環境決定使用http或https * 主機名稱:購買網域、設定DNS紀錄、應用AWS雲端服務決定主機名稱 * 埠號:透過後端程式或設定檔決定 * 路徑:透過後端程式或設定檔決定 * 要求字串:透過後端程式決定 --- ## 路由(Route) * 決定網址路徑和處理函式的對應關係 * 前端輸入不同路徑時,後端程式要決定對應的處理函式 * 例: * https://127.0.0.1/ * https://127.0.0.1/getData * 一般路由設定 ``` @app.route("/") # 路由裝飾器 def index(): return "Hello Flask !!!" ``` * 動態路由設定 ``` @app.route("/uesr/<name>") def getUser(name): return "Hello" + name ``` ## 靜態檔案處理 Static Files * 不執行程式,直接將檔案送回前端 * 直接將**檔案名稱**對應到**網址路徑** ### 靜態檔案預設路徑 * 程式不須任何更動 1. 建立static資料夾 2. 將檔案放入static資料夾 3. 啟動伺服器 4. 前端使用/static/檔案名稱 連線取得檔案 ### 自訂路徑 * 程式建立Application物件時,透過參數設定 ``` Flask( __name__. static_folder="資料夾名稱" static_url_path="對應的網址路徑" ) ``` ## Http Request * 前端立場: * 主動**發出請求**給後端伺服器,並且附帶上相關資訊 * 後端立場: * 被動從前端**接收請求**,並且取得其中附帶的相關資訊 ### 接收請求 * Flask 接收請求的流程 * 前端發送請求 * Flask套件協助我們處理網路連線底層:負責接收請求,並且將相關資訊封裝在request物間之中 * 根據路由,決定要怎麼處理 ### 使用Flask request物件 * 使用方式: * 載入request物件 * 在路由對應的函式中直接使用request取得物件 * 進一步取得相關資訊 * 使用request物件的各種屬性 * method 請求方法 * scheme 通訊協定 * host 主機名稱 * path 路徑 * url 完整網址 * 使用request物件的headers屬性(常見) * user-agent * accept-language * referrer ## 要求字串處理 * 網址的一部分(?Query String) ### 要求字串的格式 * 參數名稱 * 參數名稱=資料&參數名稱=資料&... * 例:https://www.google.com/search?q=test&rlz=1C1ONGR_zh-TWTW997TW997&oq=test&aqs=chrome..69i57j35i39j0i131i433i512l2j0i512j0i433i512j0i3j0i131i433i512j0i433i512j0i131i433i512.761j0j15&sourceid=chrome&ie=UTF-8 ### 要求字串之操作 * 在相同路徑,提供不同的要求字串 * 程式語法 * request.args.get("參數名稱", 預設值) ``` @app.route("/getSum") def getSum(): data = request.args.get("max", NOne) return data ``` ## 回應方式(Response) ### 回應前端的方式 1. 直接回應字串 * 在路由的處理函式中,回應想要回應的字串 ``` @app.route("/") def index(): return 字串 ``` 2. 回應JSON的字串 * 透過json.dumps()將字點型態的資料轉成JSON格式字串 ``` @app.route("/") def index(): return json.dumps(字典) ``` 3. 重新導向 * 透過redirect()將使用者導向到特定網址 ``` @app.route("/") def index(): return redirect(網址路徑) ``` ## 樣板引擎 Template Engine * 方便撰寫複雜的前端程式 * 方便在回應中,動態的帶入資料 ### 建立樣版檔案 * 最基本的樣本檔案就是純文字檔 * 樣板檔案必須建立在專案的templates 子資料夾底下 * 透過render_template()根據樣板檔案的內容產生文字串 ``` @app.route("/") def index(): return render_template( 檔案路徑, 資料欄位名稱=資料 ) ``` ## 表單(Form) ``` <from action="網址路徑"> <input type="test" name="data"/> -> 發出請求到 網址路徑?data=使用者的輸入 <button>點擊送出表單</button> </from> ``` ## 連線方法 * 網址:收件地址 * 方法:普通信件、限時快遞 * 方法: * 常見:<font color="red">GET、POST</font> * 其他:PUT、DELETE、PATCH ### GET * 表單就為GET method (預設) * 前端 ``` <from action="網址路徑" method="GET"> <input type="test" name="data"/> -> 使用GET方法發出請求到 網址路徑?data=使用者的輸入 <button>點擊送出表單</button> </from> ``` * 後端 ``` @app.route("網址路徑", methods=["GET"]) def hendle(): input = request.args.get("data", "") return "給前端的回應" ``` ### POST * 前端 ``` <from action="網址路徑" method="POST"> <input type="test" name="data"/> -> 使用POST方法發送請求到網址路徑 <button>點擊送出表單</button> </from> ``` * 使用POST方法發送請求到網址路徑 <font color="red">data=使用者輸入 </font> 不顯示在網址後面,另外存放 * 後端 ``` @app.route("網址路徑", methods=["POST"]) # 一定要寫POST def hendle(): input = request.form["data"] return "給前端的回應" ``` * 較機密的資料就使用POST ### 前後端互動 * 直接輸入網址:GET * 超連結:GET * 表單:可設定GET或POST * 前後端的連線method要一致 ## 使用者狀態管理(Session) * 後端並不會紀錄使用者者的狀態 ## 管理使用者狀態 * 讓後端記得前端所傳的一些資訊 * 建立session保存資料->從session取得資料 ``` // 連線至 /hello?name=安安 name = request.args.get("name", None) session["data"] = name return "你好," + name ``` * session資料為 * session["欄位名稱"] = 資料