2

I have written a simple web application in Go that needs to read values of an HTTP form (username, password) etc. However, I found that the values were empty when printed. len(r.Form) and len(r.Form["password"]) both return 0.

I have called r.ParseForm() in the application before trying to read the fields and I'm using Postman to send the requests. Tested on both Linux and macOS.

The code I am using to test this is some example code from the Astaxie golang web tutorial. I have attached my Postman request. It looks like this so far:

package main

import (
    "fmt"
    "html/template"
    "log"
    "net/http"
    "strings"
    "time"
)

func sayhelloName(w http.ResponseWriter, r *http.Request) {
    r.ParseForm() //Parse url parameters passed, then parse the response packet for the POST body (request body)
    // attention: If you do not call ParseForm method, the following data can not be obtained form
    fmt.Println(r.Form) // print information on server side.
    fmt.Println("path", r.URL.Path)
    fmt.Println("scheme", r.URL.Scheme)
    fmt.Println(r.Form["url_long"])
    for k, v := range r.Form {
        fmt.Println("key:", k)
        fmt.Println("val:", strings.Join(v, ""))
    }
    fmt.Fprintf(w, "Hello astaxie!") // write data to response
}

func login(w http.ResponseWriter, r *http.Request) {
    fmt.Println("method:", r.Method) //get request method
    if r.Method == "GET" {
        t, _ := template.ParseFiles("login.gtpl")
        t.Execute(w, nil)
    } else {
        r.ParseForm()
        time.Sleep(3 * time.Second)
        // logic part of log in
        fmt.Println("username:", len(r.Form))
        fmt.Println("password:", len(r.Form["password"]))
    }

}

func main() {
    http.HandleFunc("/", sayhelloName) // setting router rule
    http.HandleFunc("/login", login)
    err := http.ListenAndServe(":9090", nil) // setting listening port
    if err != nil {
        log.Fatal("ListenAndServe: ", err)
    }
}

Any suggestions on what to do next?

Thanks!

2 Answers 2

6

try changing the content-type on your Postman request from form-data to x-www-form-urlencoded

Because according to the docs on r.ParseForm() the body won't be parsed unless it's x-www-form-urlencoded

For other HTTP methods, or when the Content-Type is not application/x-www-form-urlencoded, the request Body is not read, and r.PostForm is initialized to a non-nil, empty value.

Sign up to request clarification or add additional context in comments.

Comments

0

I suggest you first check content type then read form data with request.FormValue("example") if you use form you always check key is valid in map or not and if you don't It's make a runtime error.

func login(w http.ResponseWriter, r *http.Request) {
    fmt.Println("method:", r.Method) //get request method
    if r.Method == "GET" {
        t, _ := template.ParseFiles("login.gtpl")
        t.Execute(w, nil)
    } else {
        fmt.Println("username:", r.FormValue("username"))
        fmt.Println("password:", r.FormValue("password"))
    }

}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.