3 回答

TA貢獻(xiàn)2037條經(jīng)驗(yàn) 獲得超6個(gè)贊
有沒有更簡單的方法可以像 PHP 那樣將我的表單數(shù)組作為 Golang 中的實(shí)際地圖?
您可以使用PostForm該http.Request類型的成員。它是一種類型url.Values——實(shí)際上是 (ta-da) a map[string][]string,你可以這樣對待它。不過,您仍然需要先打電話req.ParseForm()。
if err := req.ParseForm(); err != nil {
// handle error
}
for key, values := range req.PostForm {
// [...]
}
請注意,這PostForm是字符串列表的映射。這是因?yàn)槔碚撋?,每個(gè)字段都可以在 POST 正文中出現(xiàn)多次。該P(yáng)ostFormValue()方法通過隱式返回多個(gè)值中的第一個(gè)來處理此問題(意思是,當(dāng)您的 POST 正文為 時(shí)&foo=bar&foo=baz,req.PostFormValue("foo")則將始終返回"bar")。
另請注意,PostForm永遠(yuǎn)不會(huì)像您在 PHP 中使用的那樣包含嵌套結(jié)構(gòu)。由于 Go 是靜態(tài)類型的,POST 表單值將始終是string(name) 到[]string(value/s)的映射。
就個(gè)人而言,我不會(huì)contact[email]在 Go 應(yīng)用程序中對 POST 字段名稱使用括號語法 ( );這是一個(gè) PHP 特定的構(gòu)造,無論如何,正如您已經(jīng)注意到的,Go 并沒有很好地支持它。
我是應(yīng)該一個(gè)一個(gè)地檢索數(shù)據(jù)(很乏味,我可能會(huì)在某個(gè)時(shí)候更改表單數(shù)據(jù)并重新編譯...)還是像我在第二個(gè)示例中所做的那樣迭代整個(gè)過程。
可能沒有正確的答案。如果您將 POST 字段映射到具有靜態(tài)字段的結(jié)構(gòu),則必須在某個(gè)時(shí)候顯式映射它們(或用于reflect實(shí)現(xiàn)一些神奇的自動(dòng)映射)。

TA貢獻(xiàn)1852條經(jīng)驗(yàn) 獲得超1個(gè)贊
我有一個(gè)類似的問題,所以我寫了這個(gè)函數(shù)
func ParseFormCollection(r *http.Request, typeName string) []map[string]string {
var result []map[string]string
r.ParseForm()
for key, values := range r.Form {
re := regexp.MustCompile(typeName + "\\[([0-9]+)\\]\\[([a-zA-Z]+)\\]")
matches := re.FindStringSubmatch(key)
if len(matches) >= 3 {
index, _ := strconv.Atoi(matches[1])
for ; index >= len(result); {
result = append(result, map[string]string{})
}
result[index][matches[2]] = values[0]
}
}
return result
}
它將表單鍵值對的集合轉(zhuǎn)換為字符串映射列表。例如,如果我有這樣的表單數(shù)據(jù):
Contacts[0][Name] = Alice
Contacts[0][City] = Seattle
Contacts[1][Name] = Bob
Contacts[1][City] = Boston
我可以調(diào)用我的函數(shù)傳遞“聯(lián)系人”的類型名稱:
for _, contact := range ParseFormCollection(r, "Contacts") {
// ...
}
它將返回一個(gè)包含兩個(gè)地圖對象的列表,每個(gè)地圖都包含“名稱”和“城市”的鍵。在 JSON 表示法中,它看起來像這樣:
[
{
"Name": "Alice",
"City": "Seattle"
},
{
"Name": "Bob",
"City": "Boston"
}
]
順便說一句,這正是我在 ajax 請求中將數(shù)據(jù)發(fā)布到服務(wù)器的方式:
$.ajax({
method: "PUT",
url: "/api/example/",
dataType: "json",
data: {
Contacts: [
{
"Name": "Alice",
"City": "Seattle"
},
{
"Name": "Bob",
"City": "Boston"
}
]
}
})
如果您的表單數(shù)據(jù)鍵結(jié)構(gòu)與我的不太匹配,那么您可能會(huì)調(diào)整我正在使用的正則表達(dá)式以滿足您的需求。

TA貢獻(xiàn)1891條經(jīng)驗(yàn) 獲得超3個(gè)贊
我有同樣的問題。在我來自的 Ruby/Rails 世界中,數(shù)組表單參數(shù)的提交也是慣用的。但是,經(jīng)過一些研究,看起來這并不是真正的“Go-way”。
我一直在使用點(diǎn)前綴約定:contact.name,contact.email,等。
func parseFormHandler(writer http.ResponseWriter, request *http.Request) {
request.ParseForm()
userParams := make(map[string]string)
for key, _ := range request.Form {
if strings.HasPrefix(key, "contact.") {
userParams[string(key[8:])] = request.Form.Get(key)
}
}
fmt.Fprintf(writer, "%#v\n", userParams)
}
func main() {
server := http.Server{Addr: ":8088"}
http.HandleFunc("/", parseFormHandler)
server.ListenAndServe()
}
運(yùn)行此服務(wù)器,然后將其卷曲:
$ curl -id "contact.name=Jeffrey%20Lebowski&contact.email=thedude@example.com&contact.message=I%20hate%20the%20Eagles,%20man." http://localhost:8088
結(jié)果是:
HTTP/1.1 200 OK
Date: Thu, 12 May 2016 16:41:44 GMT
Content-Length: 113
Content-Type: text/plain; charset=utf-8
map[string]string{"name":"Jeffrey Lebowski", "email":"thedude@example.com", "message":"I hate the Eagles, man."}
使用大猩猩工具包
您還可以使用Gorilla Toolkit 的 Schema Package將表單參數(shù)解析為結(jié)構(gòu)體,如下所示:
type Submission struct {
Contact Contact
}
type Contact struct {
Name string
Email string
Message string
}
func parseFormHandler(writer http.ResponseWriter, request *http.Request) {
request.ParseForm()
decoder := schema.NewDecoder()
submission := new(Submission)
err := decoder.Decode(submission, request.Form)
if err != nil {
log.Fatal(err)
}
fmt.Fprintf(writer, "%#v\n", submission)
}
運(yùn)行此服務(wù)器,然后將其卷曲:
$ curl -id "Contact.Name=Jeffrey%20Lebowski&Contact.Email=thedude@example.com&Contact.Message=I%20hate%20the%20Eagles,%20man." http://localhost:8088
結(jié)果是:
HTTP/1.1 200 OK
Date: Thu, 12 May 2016 17:03:38 GMT
Content-Length: 128
Content-Type: text/plain; charset=utf-8
&main.Submission{Contact:main.Contact{Name:"Jeffrey Lebowski", Email:"thedude@example.com",
- 3 回答
- 0 關(guān)注
- 231 瀏覽
添加回答
舉報(bào)