如何在Go服务器中提取POST参数

huangapple go评论89阅读模式
英文:

How to extract the post arguments in go server

问题

如何提取发送到localhost:8080/something URL的POST数据?

英文:

Below is an server written in go.

package main

import (
    "fmt"
    "net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hi there, I love %s!", r.URL.Path[1:])
    fmt.Fprintf(w,"%s",r.Method)
}

func main() {
    http.HandleFunc("/", handler)
    http.ListenAndServe(":8080", nil)
}

How can I extract the POST data sent to the localhost:8080/something URL?

答案1

得分: 38

func handler(w http.ResponseWriter, r *http.Request) {
r.ParseForm() // 解析请求体
x := r.Form.Get("parameter_name") // 如果参数未设置,x将为空字符串
fmt.Println(x)
}

英文:

Like this:

func handler(w http.ResponseWriter, r *http.Request) {
    r.ParseForm()                     // Parses the request body
    x := r.Form.Get("parameter_name") // x will be "" if parameter is not set
    fmt.Println(x)
}

答案2

得分: 7

// Form包含解析后的表单数据,包括URL字段的查询参数和POST或PUT表单数据。
// 只有在调用ParseForm之后,该字段才可用。
// HTTP客户端忽略Form字段,而使用Body字段。
Form url.Values

英文:

Quoting from the documentation of http.Request

// Form contains the parsed form data, including both the URL
// field's query parameters and the POST or PUT form data.
// This field is only available after ParseForm is called.
// The HTTP client ignores Form and uses Body instead.
Form url.Values

答案3

得分: 3

要从POST请求中提取一个值,首先要调用r.ParseForm()这个会解析URL中的原始查询,并更新r.Form。

> 对于POST或PUT请求,它还会将请求体解析为一个表单,并将结果放入r.PostForm和r.Form中。POST和PUT请求体参数优先于r.Form中的URL查询字符串值。

现在你的r.Form是客户端提供的所有值的映射。要提取特定的值,可以使用r.FormValue("<your param name>")r.Form.Get("<your param name>")

你也可以使用r.PostFormValue

英文:

To extract a value from a post request you have to call r.ParseForm() at first. This parses the raw query from the URL and updates r.Form.

> For POST or PUT requests, it also parses the request body as a form
> and put the results into both r.PostForm and r.Form. POST and PUT body
> parameters take precedence over URL query string values in r.Form.

Now your r.From is a map of all values your client provided. To extract a particular value you can use r.FormValue(&quot;&lt;your param name&gt;&quot;) or r.Form.Get(&quot;&lt;your param name&gt;&quot;).

You can also use r.PostFormValue.

答案4

得分: 3

对于POSTPATCHPUT请求:

首先我们调用r.ParseForm()将POST请求体中的任何数据添加到r.PostForm映射中

err := r.ParseForm()
if err != nil {
	// 如果出现任何错误
	return
}

// 使用r.PostForm.Get()方法从r.PostForm映射中检索相关数据字段
value := r.PostForm.Get("parameter_name")

对于POSTGETPUT等(对于所有请求):

err := r.ParseForm()
if err != nil {
	// 如果出现任何错误
	return
}

// 使用r.Form.Get()方法从r.Form映射中检索相关数据字段
value := r.Form.Get("parameter_name") // 注意!是r.Form,而不是r.PostForm

Form方法

相反,r.Form映射适用于所有请求(无论其HTTP方法如何),并包含来自任何请求体和任何查询字符串参数的表单数据。因此,如果我们的表单提交到/snippet/create?foo=bar,我们也可以通过调用r.Form.Get("foo")来获取foo参数的值。请注意,在冲突的情况下,请求体值将优先于查询字符串参数。

FormValuePostFormValue方法

net/http包还提供了r.FormValue()和r.PostFormValue()方法。这些本质上是调用r.ParseForm()的快捷函数,然后从r.Form或r.PostForm中获取相应的字段值。我建议避免使用这些快捷方式,因为它们会默默地忽略r.ParseForm()返回的任何错误。这并不理想-这意味着我们的应用程序可能会遇到错误并对用户失败,但没有反馈机制来让他们知道。

所有示例都来自于关于Go的最佳书籍 - 《Let's Go! Learn to Build Professional Web Applications With Golang》。这本书可以回答你所有的问题!

英文:

For POST, PATCH and PUT requests:

First we call r.ParseForm() which adds any data in POST request bodies to the r.PostForm map

err := r.ParseForm()
if err != nil {
	// in case of any error
	return
}

// Use the r.PostForm.Get() method to retrieve the relevant data fields
// from the r.PostForm map.
value := r.PostForm.Get(&quot;parameter_name&quot;)

For POST, GET, PUT and etc (for all requests):

err := r.ParseForm()
if err != nil {
	// in case of any error
	return
}

// Use the r.Form.Get() method to retrieve the relevant data fields
// from the r.Form map.
value := r.Form.Get(&quot;parameter_name&quot;) // attention! r.Form, not r.PostForm 

> The Form method

> In contrast, the r.Form map is populated for all requests
> (irrespective of their HTTP method), and contains the form data from
> any request body and any query string parameters. So, if our form was
> submitted to /snippet/create?foo=bar, we could also get the value of
> the foo parameter by calling r.Form.Get("foo"). Note that in the event
> of a conflict, the request body value will take precedent over the
> query string parameter.
>
> The FormValue and PostFormValue Methods
>
> The net/http package also provides the methods r.FormValue() and
> r.PostFormValue(). These are essentially shortcut functions that call
> r.ParseForm() for you, and then fetch the appropriate field value from
> r.Form or r.PostForm respectively. I recommend avoiding these shortcuts
> because they silently ignore any errors returned by r.ParseForm().
> That’s not ideal — it means our application could be encountering
> errors and failing for users, but there’s no feedback mechanism to let
> them know.

All samples are from the best book about Go - Let's Go! Learn to Build Professional Web Applications With Golang. This book can answer to all of your questions!

答案5

得分: 0

对于普通请求:

r.ParseForm()
value := r.FormValue("value")

对于多部分请求:

r.ParseForm()
r.ParseMultipartForm(32 << 20)
file, _, _ := r.FormFile("file")
英文:

For normal Request:

r.ParseForm()
value := r.FormValue(&quot;value&quot;)

For multipart Request:

r.ParseForm()
r.ParseMultipartForm(32 &lt;&lt; 20)
file, _, _ := r.FormFile(&quot;file&quot;)

答案6

得分: 0

package main

import (
  "fmt"
  "log"
  "net/http"
  "strings"
)


func main() {
  // the forward slash at the end is important for path parameters:
  http.HandleFunc("/testendpoint/", testendpoint)
  err := http.ListenAndServe(":8888", nil)
  if err != nil {
    log.Println("ListenAndServe: ", err)
  }
}

func testendpoint(w http.ResponseWriter, r *http.Request) {
  // If you want a good line of code to get both query or form parameters
  // you can do the following:
  param1 := r.FormValue("param1")
  fmt.Fprintf( w, "Parameter1:  %s ", param1)

  //to get a path parameter using the standard library simply
  param2 := strings.Split(r.URL.Path, "/")

  // make sure you handle the lack of path parameters
  if len(param2) > 4 {
    fmt.Fprintf( w, " Parameter2:  %s", param2[5])
  }
}
英文:
package main

import (
  &quot;fmt&quot;
  &quot;log&quot;
  &quot;net/http&quot;
  &quot;strings&quot;
)


func main() {
  // the forward slash at the end is important for path parameters:
  http.HandleFunc(&quot;/testendpoint/&quot;, testendpoint)
  err := http.ListenAndServe(&quot;:8888&quot;, nil)
  if err != nil {
    log.Println(&quot;ListenAndServe: &quot;, err)
  }
}

func testendpoint(w http.ResponseWriter, r *http.Request) {
  // If you want a good line of code to get both query or form parameters
  // you can do the following:
  param1 := r.FormValue(&quot;param1&quot;)
  fmt.Fprintf( w, &quot;Parameter1:  %s &quot;, param1)

  //to get a path parameter using the standard library simply
  param2 := strings.Split(r.URL.Path, &quot;/&quot;)

  // make sure you handle the lack of path parameters
  if len(param2) &gt; 4 {
    fmt.Fprintf( w, &quot; Parameter2:  %s&quot;, param2[5])
  }
}

You can run the code in aapi playground <a href="http://play.aapi.io?share=TOMOEKJRTEMSGJTAWNXVJEUJPBGTDNIUNNYQSDLY">here</a>

Add this to your access url: /mypathparameeter?param1=myqueryparam

I wanted to leave the link above for now, because it gives you a nice place to run the code, and I believe its helpful to be able to see it in action, but let me explain some typical situations where you might want a post argument.

There are a few typical ways developers will pull post data to a back end server, usually multipart form data will be used when pulling files from the request, or large amounts of data, so I don't see how thats relevant here, at least in the context of the question. He is looking for post arguments which typically means form post data. Usually form post arguments are sent in a web form to the back end server.

  1. When a user is submitting a login form or registration data back to golang from html, the Content Type header coming from the client in this case would be application/x-www-form-urlencoded typically, which I believe is what the question is asking, these would be form post arguments, which are extracted with r.FormValue("param1").

  2. In the case of grabbing json from the post body, you would grab the entire post body and unmarshal the raw json into a struct, or use a library to parse the data after you have pulled the data from the request body, Content Type header application/json.

Content Type header is largely responsible for how you will parse the data coming from the client, I have given an example of 2 different content types, but there are many more.

答案7

得分: 0

只想添加如何在Go服务器中提取Post参数的方法,如果您正在使用JSON数据进行工作,这在构建API时经常发生。

...

//...

package main

import (
	"encoding/json"
	"fmt"
	"net/http"
)


//在GoLang中使用JSON时,我更喜欢使用结构体,所以我在这里创建了结构体

type JSONData struct {
	// 这里应该包含预期的JSON数据
	// <key> <data type> `json: <where to find the data in the JSON>` 在这种情况下,我们有
	Name string `json:"name"`
	Age  string `json:"age"`
}

func handler(w http.ResponseWriter, r *http.Request) {
	decoder := json.NewDecoder(r.Body)
	var data JSONData
	error := decoder.Decode(&data)
	if error != nil {
		fmt.Println("解码数据时发生错误: ", error)
		return
	}
	fmt.Println("name: \t", data.Name, " \n  age: \t ", data.Age)

}

func main() {
    http.HandleFunc("/", handler)
    http.ListenAndServe(PORT, nil)
}

// ...
// 和你的其他代码
英文:

Just wanted to add how to extract the Post arguments in Go server in case you are working with JSON data which often is the case while building an API
...

//...

package main

import (
	&quot;encoding/json&quot;
	&quot;fmt&quot;
	&quot;net/http&quot;
)


//While working with JSON in GoLang I prefer using structs so I created the struct here

type JSONData struct {
	// This should contain the expected JSON data
	// &lt;key&gt; &lt;data type&gt; `json: &lt;where to find the data in the JSON` in this case we have
	Name string `json:&quot;name&quot;`
	Age  string `json:&quot;age&quot;`
}

func handler(w http.ResponseWriter, r *http.Request) {
	decoder := json.NewDecoder(r.Body)
	var data JSONData
	error := decoder.Decode(&amp;data)
	if error != nil {
		fmt.Println(&quot;Error occured while decoding the data: &quot;, error)
		return
	}
	fmt.Println(&quot;name: \t&quot;, data.Name, &quot; \n  age: \t &quot;, data.Age)

}

func main() {
    http.HandleFunc(&quot;/&quot;, handler)
    http.ListenAndServe(PORT, nil)
}

// ...
// and the rest of your codes

huangapple
  • 本文由 发表于 2013年5月13日 05:02:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/16512009.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定