GET 和 POST 是我們最常用的兩種請求方式,今天結合前端 axios 請求庫來講一講,如何在 golang 服務中,正確接收這兩種請求的參數信息。
一、搭建一個簡單的服務
首先,我們來創建一個最簡單的靜態頁面,將 axios 引進來:
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
GET & POST
</body>
</html>
接下來,我們寫一個簡單的 golang 服務程序,在瀏覽器端訪問這個服務時,將上面的靜態頁面內容返回給瀏覽器:
package main
import (
"log"
"fmt"
"net/http"
"html/template"
)
// 返回靜態頁面
func handleIndex(writer http.ResponseWriter, request *http.Request) {
t, _ := template.ParseFiles("index.html")
t.Execute(writer, nil)
}
func main() {
http.HandleFunc("/", handleIndex)
fmt.Println("Running at port 3000 ...")
err := http.ListenAndServe(":3000", nil)
if err != nil {
log.Fatal("ListenAndServe: ", err.Error())
}
}
運行上面程序,然后在瀏覽器中訪問 localhost:3000,就可以看到一個簡單的靜態頁面了。
二、處理 GET 請求
接下來,我們就在靜態頁面中添加一個 GET 請求:
<script>
axios.get('/testGet', {
params: {
id: 1,
}
}).then((response) => {
console.log(response);
});
</script>
對應地,服務端也要添加這個請求路徑的處理函數:
// 處理GET請求
func handleGet(writer http.ResponseWriter, request *http.Request) {
query := request.URL.Query()
// 第一種方式
// id := query["id"][0]
// 第二種方式
id := query.Get("id")
fmt.Printf("GET: id=%s\n", id)
fmt.Fprintf(writer, `{"code":0}`)
}
func main() {
// ...
http.HandleFunc("/testGet", handleGet)
// ...
}
重新運行程序,訪問頁面,服務端控制台打印如下:
GET: id=1
在接收到請求參數后,我們會返回一個 {"code":0} 的響應結果,瀏覽器端收到響應后,會將其轉為 JS 對象,控制台打印如下:
三、處理 POST 請求
在開發中,常用的 POST 請求有兩種,分別是 application/json 和 application/x-www-form-urlencoded,下面就來介紹一下這兩種類型的處理方式。
先說第一種,在使用 axios 發起請求時,默認就是 application/json 類型,我們來添加一個這樣的請求:
// POST數據
const postData = {
username: 'admin',
password: '123',
};
axios.post('/testPostJson', postData).then((response) => {
console.log(response);
});
同樣地,我們需要在 golang 服務中添加處理函數:
// 引入encoding/json包
import (
// ...
"encoding/json"
)
// 處理application/json類型的POST請求
func handlePostJson(writer http.ResponseWriter, request *http.Request) {
// 根據請求body創建一個json解析器實例
decoder := json.NewDecoder(request.Body)
// 用於存放參數key=value數據
var params map[string]string
// 解析參數 存入map
decoder.Decode(¶ms)
fmt.Printf("POST json: username=%s, password=%s\n", params["username"], params["password"])
fmt.Fprintf(writer, `{"code":0}`)
}
func main() {
// ...
http.HandleFunc("/testPostJson", handlePostJson)
// ...
}
再次運行程序,訪問頁面,服務端控制台打印如下:
POST json: username=admin, password=123
如果我們使用 application/x-www-form-urlencoded 這樣的請求類型,就需要在發送請求時,額外添加一些配置信息:
// POST數據
const postData = {
username: 'admin',
password: '123',
};
axios.post('/testPostForm', postData, {
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
},
transformRequest: [(data) => {
const pairs = [];
Object.keys(data).forEach(key => {
pairs.push(`${key}=${data[key]}`);
});
return pairs.join('&');
}]
}).then((response) => {
console.log(response);
});
對應的服務端 golang 處理函數如下:
// 處理application/x-www-form-urlencoded類型的POST請求
func handlePostForm(writer http.ResponseWriter, request *http.Request) {
request.ParseForm()
// 第一種方式
// username := request.Form["username"][0]
// password := request.Form["password"][0]
// 第二種方式
username := request.Form.Get("username")
password := request.Form.Get("password")
fmt.Printf("POST form-urlencoded: username=%s, password=%s\n", username, password)
fmt.Fprintf(writer, `{"code":0}`)
}
func main() {
// ...
http.HandleFunc("/testPostForm", handlePostForm)
// ...
}
最后運行程序並訪問,服務端控制台打印如下:
POST form-urlencoded: username=admin, password=123
四、返回JSON對象數據
前面我們的處理函數中,都返回了一個簡單的 JSON 字符串,實際開發中,往往是一些數據對象,我們需要將這些數據對象以 JSON 的形式返回,下面我們就來添加一段代碼:
type Person struct {
Name string `json:"name"`
Age int `json:"age"`
}
type Response struct {
Code int `json:"code"`
Msg string `json:"msg"`
Data Person `json:"data"`
}
// 返回數據對象的JSON數據
func handleResponseJson(writer http.ResponseWriter, request *http.Request) {
res := Response{
0,
"success",
Person{
"Jack",
20,
},
}
json.NewEncoder(writer).Encode(res)
}
func main() {
// ...
http.HandleFunc("/handleResponseJson", handleResponseJson)
// ...
}
接着,我們使用 axios 測試一下這個服務:
axios.get('/handleResponseJson').then((response) => {
console.log(response);
});
訪問頁面,瀏覽器控制台打印結果如下: