0、GET/POST 請求資料
在 PHP 中,可以直接通過全局變量
$_GET
和
$_POST
快速擷取 GET/POST 請求資料,GET 請求資料主要是 URL 查詢字元串中包含的參數,以前面線上論壇項目的群組詳情頁為例:
上述 URL 請求中的
id=adb02107-d7c3-4f27-4de4-b586f231380e
就屬于 GET 請求資料,也就是查詢字元串,而對于使用者登入表單:
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5iZlNDNkNzNlFmZhZTY2UTNmRTZ5Q2YxUDMiBjYwYmM48CX0JXZ252bj91Ztl2Lc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
當使用者輸入注冊郵箱和密碼後點選「登入」按鈕,會将輸入框中的資料作為請求實體發送 POST 請求到服務端,執行登入認證,這裡的表單資料就是 POST 請求資料,如果我們檢視表單請求路由的 HTTP 封包:
就會看到表單請求資料,也就是上文提到的 HTTP 請求實體。
當然根據對服務端資源的操作類型不同,可以進一步細分為 POST、PUT、PATCH、DELETE 等包含請求實體的請求方法,為了簡化模型,我們這裡隻讨論 POST 請求,而且其他幾種請求方法也可以統一通過 POST 請求完成,通常隻有在設計遵循 RESTful 風格的 API 接口時,才會嚴格劃分不同的請求方法,關于這一點,後面介紹 REST + JSON 接口時再詳細讨論。
1、Form
Go 語言中擷取使用者請求資料的方式要更複雜一些,Go 也為此提供多個不同的結構體幫助我們讀取不同請求類型的資料,首先,我們可以通過請求對象上的
Form
讀取所有 GET/POST 請求資料,在
handlers/post.go
中新增
EditPost
方法如下:
需要注意的是,在通過
r.Form
擷取所有請求資料之前,必須要先通過
r.ParseForm()
解析所有請求資料,否則無法擷取資料。
在
routes/web.go
中新增一個路由:
然後我們重新開機 HTTP 伺服器,在指令行通過 curl 發起一個包含不同類型請求資料的請求:
可以看到,列印結果表明
r.Form
是一個包含所有請求資料的字典類型(map),包含 URL 查詢字元串和 POST 請求資料,這是一個 POST 請求,如果是 GET 請求呢?我們為
EditPost
定義一個 GET 請求路由:
再重新開機 HTTP 伺服器,發起一個隻包含查詢字元串的 GET 請求(預設是 GET 請求,不需要通過
-X GET
指定):
同樣可以列印出和 POST 請求完全一樣的結果。
是以,
request
對象上的
Form
可以擷取所有請求參數,包括查詢字元串和請求實體,并且不限請求類型。如果你想要進一步要擷取指定的參數值,可以以索引方式擷取指定參數對應的值,也可以通過
Form
提供的
Get
方法,就像我們從一個普通字典類型擷取鍵值一樣:
隻不過兩者的傳回值類型不一樣,前者是一個字元串切片,後者是一個字元串值:
2、PostForm
上面的結果同時傳回了查詢字元串和請求實體,如果隻想擷取請求實體(即 POST 表單中的資料),可以通過
PostForm
實作:
這樣一來,就隻能擷取到 POST 資料了:
然後在 HTTP 伺服器日志,可以看到如下答應結果:
可以看到
r.PostForm
傳回的也是字典類型資料,資料格式和
r.Form
完全一緻,并且這次隻包含了 POST 表單請求資料,不包含 URL 查詢字元串,也就是說,通過
r.PostForm
隻能擷取 POST 請求資料(請求實體資料),無法擷取 GET 請求資料(查詢字元串中的資料),你可以再次發起 GET 請求進行驗證:
這個時候,可以看到伺服器列印日志之包含
id
資訊,表單資訊為空:
通過
PostForm
擷取具體參數值的方式和
Form
一樣,這裡就不再贅述了:
實際上,我們在前面的線上論壇項目中,就是通過這個方式擷取表單請求資料的:
3、FormValue/PostFormValue
最後,還可以通過
FormValue
和
PostFormValue
擷取使用者請求資料,使用它們的好處是不再需要單獨調用
ParseForm
對表單資料進行解析,不過使用這兩個方法的時候隻能擷取特定請求資料,不能一次擷取所有請求資料:
FormValue
/
PostFormValue
的差別和
Form/PostForm
一樣,這裡通過命名就可以看出來,前者可以擷取所有 GET/POST 請求資料(即查詢字元串和請求實體),後者隻能擷取 POST 請求實體資料。
注:/
FormValue
之是以不用顯式調用
PostFormValue
解析請求資料,是因為底層對其進行了封裝,實際上還是要調用這個方法。
ParseForm
4、擷取 JSON 請求資料
上面的示例預設都是基于 HTML 表單請求,對于用戶端送出的 JSON 格式資料,使用
ParseForm
是無法解析并擷取資料的,因為 HTML 表單請求資料預設是通過
application/x-www-form-urlencoded
編碼的,而 JSON 請求資料通常是通過
application/json
編碼,
ParseForm
隻能解析通過
application/x-www-form-urlencoded
編碼的資料。
對于 JSON 請求資料的解析,目前我們可以通過上篇教程介紹的,讀取完整請求實體并進行 JSON 解碼實作,下面我們改寫
AddPost
方法實作如下:
我們将讀取的請求實體資料通過 JSON 解碼映射到 Post 結構體對象并将其輸出到響應結果。
重新開機 HTTP 伺服器,通過 curl 模拟用戶端送出 JSON 請求資料:
我們通過
-H
選項指定請求資料編碼格式為
application/json
,然後請求資料調整為 JSON 格式字元串,最後通過輸出結果可以看到在服務端 JSON 請求資料已經可以成功解析并擷取。
5、小結
到這裡,我們已經了解了在 Go Web 程式設計中,常見的使用者請求資料如何解析并擷取(URL 查詢字元串、POST 表單資料、JSON 請求資料),實際上,和 PHP 中的
$_GET
和
$_POST
類似,Go 也是将 HTTP 請求資料映射到請求對象對應的結構體,然後開發者可以從上下文請求對象中解析并讀取這些請求資料,使用這些封裝好的對象的好處是它們屏蔽了底層的細節,統一了資料格式,可以大大提高開發效率,減少不必要的資料格式相容成本。
下篇教程,學院君将給大家介紹如何從表單請求中擷取檔案資料,并實作簡單的檔案上傳功能。
(全文完)
推薦閱讀
- Go 語言 Web 程式設計系列 —— 通過 Request 讀取 HTTP 請求封包
喜歡本文的朋友,歡迎關注“Go語言中文網”:
Go語言中文網啟用微信學習交流群,歡迎加微信:274768166,投稿亦歡迎