dongmi0760 2015-03-12 07:33
浏览 13
已采纳

Golang html GET表单方法值未填充

I have a server code and a html form to search a string. Server handler gets the string and search for the same. But I am facing two issues here.

1.Method name is always GET even after I made it as POST.

2.I am Not able to receive the form value in the server end

Server code is here,

package main

import (
    "flag"
    "fmt"
    "html/template"
    "io/ioutil"
    "log"
    "net"
    "net/http"
    "regexp"
    //"bytes"
)

var (
    addr = flag.Bool("addr", false, "find open address and print to final-port.txt")
)

type Page struct {
    Title string
    Body  []byte
}

type UserInfo struct {
    Title string
    UserId   string
    UserName string
}

func (p *Page) save() error {
    filename := "projects/" + p.Title + ".txt"
    return ioutil.WriteFile(filename, p.Body, 0600)
}

func loadPage(title string) (*Page, error) {
    filename := "projects/" + title + ".txt"
    body, err := ioutil.ReadFile(filename)
    if err != nil {
        return nil, err
    }
    return &Page{Title: title, Body: body}, nil
}

//Home page handler
//Hard coding the user name
func homeHandler(w http.ResponseWriter, r *http.Request, title string) {
    p := &UserInfo{Title: "Project Tube",UserId: "dxa132330", UserName: "Dinesh Appavoo"}
    renderTemplate(w, "home", p)
}

//Search project handler
func searchHandler(w http.ResponseWriter, r *http.Request, title string) {
    fmt.Println("method:", r.Method) //get request method
    r.ParseForm()
    if r.Method == "GET" {
    form_data := r.FormValue("form_data")
    fmt.Println("Form Data : ",form_data)
    fmt.Println("Form Data  1: ",r.Form)
    for _,val := range r.FormValue("search_string") {
        fmt.Println("Search string: ", val)
    }

    } else {
        r.ParseForm()
        fmt.Println("Search string:", r.FormValue("search_string"))
    }
    p := &UserInfo{Title: "Project Tube",UserId: "dxa132330", UserName: "Dinesh Appavoo"}
    renderTemplate(w, "searchproject", p)
}

var templates = template.Must(template.ParseFiles("home.html", "editproject.html", "viewproject.html", "searchproject.html", "header.html", "footer.html"))


func renderTemplate(w http.ResponseWriter, tmpl string, p interface{}) {

    //If you use variables other than the struct u r passing as p, then "multiple response.WriteHeader calls" error may occur. Make sure you pass 
    //all variables in the struct even they are in the header.html embedded 
    if err := templates.ExecuteTemplate(w, tmpl+".html", p); err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
    }
}

//URL validation
var validPath = regexp.MustCompile("^/(home|editproject|saveproject|viewproject|searchproject)/(|[a-zA-Z0-9]+)$")

func makeHandler(fn func(http.ResponseWriter, *http.Request, string)) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        m := validPath.FindStringSubmatch(r.URL.Path)
        if m == nil {
            http.NotFound(w, r)
            return
        }
        fn(w, r, m[2])
    }
}

func main() {
    flag.Parse()
    TestConn()
    http.HandleFunc("/home/", makeHandler(homeHandler))
    http.HandleFunc("/searchproject/", makeHandler(searchHandler))
    http.Handle("/resources/", http.StripPrefix("/resources/", http.FileServer(http.Dir("resources"))))

    if *addr {
        l, err := net.Listen("tcp", "127.0.0.1:0")
        if err != nil {
            log.Fatal(err)
        }
        err = ioutil.WriteFile("final-port.txt", []byte(l.Addr().String()), 0644)
        if err != nil {
            log.Fatal(err)
        }
        s := &http.Server{}
        s.Serve(l)
        return
    }

    http.ListenAndServe(":8080", nil)
}

I am facing issues in the searchHandler function. And my html code is here

{{ template "header.html" . }}
<br><br>
<div class="container">
    <form action="/searchproject" method="GET">
        <div class="form-group">
            <input type="text" class="form-control" name="search_string">
        </div>
        <button type="submit" class="btn btn-success">Search</button>
    </form>
</div>

server console log is as follows,

method: GET
Form Data :
Form Data  1:  map[]

Could anyone help me on this? Thanks.

  • 写回答

1条回答 默认 最新

  • dongpai2754 2015-03-13 17:12
    关注

    Thats a subtle problem you have there.

    Very subtly you have a trailing slash on the searchproject url that causes a 301 redirect to be issued from the server.

    The form does the POST (or GET) to /searchproject and the server, quite kindly says that the browser should go to /searchproject/ (trailing slash added !), which the browser does as a GET and looses the form data in the process.

    This example does what you need I think :

    package main
    
    import (
        "fmt"
        "net/http"
    )
    
    func searchHandler(w http.ResponseWriter, r *http.Request) {
        fmt.Printf("%+v
    ", r)
        fmt.Fprintln(w, "OK")
    }
    
    func homeHandler(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintln(w, SEARCH_PAGE)
    }
    
    func main() {
        http.HandleFunc("/", homeHandler)
        http.HandleFunc("/searchproject", searchHandler)
        http.ListenAndServe(":8080", nil)
    }
    
    const SEARCH_PAGE = `
    <html>
    <body>
        <form action="searchproject" method="POST">
                <input type="text" name="search_string">
                <input type="submit" value="Search">
        </form>
    </body>
    </html>
    `
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 关于#wireshark#的问题:并且能够给数据做标注,如这个流量是在看视频或者是在转账
  • ¥90 请问,这个视频播放软件的名称,用过的朋友请给答案,上方..avi是啥意思?是看短剧还是播放本地视频?
  • ¥15 运筹优化,gurobi,python
  • ¥15 基于python的电影系统推荐
  • ¥20 springmvc重定向和返回json
  • ¥15 数学建模——参会安排怎么做
  • ¥15 电脑键盘实现触摸功能
  • ¥25 matlab无法将表达式转换为双数组怎么解决?
  • ¥15 单片机汇编语言相关程序
  • ¥20 家用射频美容仪技术规格