如何在golang中处理同一个处理程序中的多个POST请求?

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

How to handle multiple POST requests in same handler in golang?

问题

我有两个表单在signup.html文件中,我想执行它们。

  1. 第一个表单重定向到/login,但不将数据插入数据库。
  2. 第二个表单既不插入数据,也不重定向到注册页面。

如果我将两个表单的action都设置为相同的链接,那么它会将数据插入数据库。如何在一个函数中执行多个POST请求并重定向到多个页面?

谢谢!

controllers.go

  1. func Signup(w http.ResponseWriter, r *http.Request) error {
  2. if r.Method == "GET" {
  3. return SignupTmpl.Execute(w, nil)
  4. } else if r.Method == "POST" && http.MethodPost == "Register" {
  5. register := models.RegisterUser{
  6. Name: r.FormValue("name"),
  7. Email: r.FormValue("email"),
  8. Password: r.FormValue("password"),
  9. }
  10. values := [3]string{register.Name, register.Email, register.Password}
  11. database.InsertRegister(values)
  12. return LoginTmpl.Execute(w, nil)
  13. } else if r.Method == "POST" && http.MethodPost == "Newsletter" {
  14. Newsletter(w, r)
  15. return SignupTmpl.Execute(w, nil)
  16. }
  17. return nil
  18. }

signup.html

  1. // 注册表单
  2. <form class="form" method="post" action="/login">
  3. ...
  4. <input type="submit" value="Register">
  5. </form>
  6. // 新闻订阅表单
  7. <form class="newsletter" method="post" action="/signup">
  8. ...
  9. <input type="submit" value="Newsletter">
  10. </form>
英文:

I have two forms in the signup.html file that I want to execute.

  1. The first form redirects to /login but does not insert the data into the database.
  2. The second form neither inserts the data nor does it redirect to the Signup page.

If I set both action equal to the same link then it inserts the data into the database. How to execute multiple POST requests and redirects to multiple pages in a
single function?

Thank you!

controllers.go

  1. func Signup(w http.ResponseWriter, r *http.Request) error {
  2. if r.Method == &quot;GET&quot; {
  3. return SignupTmpl.Execute(w, nil)
  4. } else if r.Method == &quot;POST&quot; &amp;&amp; http.MethodPost == &quot;Register&quot; {
  5. register := models.RegisterUser{
  6. Name: r.FormValue(&quot;name&quot;),
  7. Email: r.FormValue(&quot;email&quot;),
  8. Password: r.FormValue(&quot;password&quot;),
  9. }
  10. values := [3]string{register.Name, register.Email, register.Password}
  11. database.InsertRegister(values)
  12. return LoginTmpl.Execute(w, nil)
  13. } else if r.Method == &quot;POST&quot; &amp;&amp; http.MethodPost == &quot;Newsletter&quot; {
  14. Newsletter(w, r)
  15. return SignupTmpl.Execute(w, nil)
  16. }
  17. return nil
  18. }

signup.html

  1. // Signup form
  2. &lt;form class=&quot;form&quot; method=&quot;post&quot; action=&quot;/login&quot;&gt;
  3. ...
  4. &lt;input type=&quot;submit&quot; value=&quot;Register&quot;&gt;
  5. &lt;/form&gt;
  6. // Newsletter form
  7. &lt;form class=&quot;newsletter&quot; method=&quot;post&quot; action=&quot;/signup&quot;&gt;
  8. ...
  9. &lt;input type=&quot;submit&quot; value=&quot;Newsletter&quot;&gt;
  10. &lt;/form&gt;

答案1

得分: 1

  1. &gt; ```
  2. &gt; http.MethodPost == &quot;Register&quot;
  3. &gt; ...
  4. &gt; http.MethodPost == &quot;Newsletter&quot;
  5. &gt; ```
  6. 这些比较没有意义。[`http.MethodPost` 是一个常量][1],它包含了 HTTP POST 请求的动词("POST")。常量变量比硬编码的值更受欢迎,因为与硬编码的字符串不同,拼写错误会导致编译时错误。
  7. &gt;```
  8. &gt;&lt;input type=&quot;submit&quot; value=&quot;Newsletter&quot;&gt;
  9. &gt;```
  10. 如果你想要访问这个输入标签的值,你需要给它一个 `name`
  11. &gt; &lt;input type=&quot;submit&quot; name=&quot;operation&quot; value=&quot;Newsletter&quot;&gt;
  12. 然后你可以检查表单的值:

if r.Method == "GET" {
return SignupTmpl.Execute(w, nil)
} else if r.Method == "POST" {
if r.FormValue("operation") == "Register" {
...
} else if r.FormValue("operation") == "Newsletter" {
...
}
}

  1. 我个人会为所有这些操作编写不同的处理程序,然后将它们指向不同的 URL。大部分处理程序逻辑都是路由,可以通过不同的处理程序免费完成。但你现在的做法也可以 - 只需确保:
  2. 1) 给需要后续引用的输入字段命名
  3. 2) 不要将 'POST' 'POST' 进行比较,而是将命名的输入字段值与预期值进行比较
  4. [1]: https://pkg.go.dev/net/http#pkg-constants
英文:

>
&gt; http.MethodPost == &quot;Register&quot;
&gt; ...
&gt; http.MethodPost == &quot;Newsletter&quot;
&gt;

These comparisons make no sense. http.MethodPost is a constant which contains the verb for HTTP Post requests ("POST"). Constant variables are preferred to hard coded values because unlike a hard coded string, a typeo will cause a compile time error.

>
&gt;&lt;input type=&quot;submit&quot; value=&quot;Newsletter&quot;&gt;
&gt;

If you want to be able to access the value of this input tag, you need to give it a name:

> <input type="submit" name="operation" value="Newsletter">

Then you can check that form value:

  1. if r.Method == &quot;GET&quot; {
  2. return SignupTmpl.Execute(w, nil)
  3. } else if r.Method == &quot;POST&quot; {
  4. if r.FormValue(&quot;operation&quot;) == &quot;Register&quot; {
  5. ...
  6. } else if r.FormValue(&quot;operation&quot;) == &quot;Newsletter&quot; {
  7. ...
  8. }
  9. }

I personally would write a different handler for all these operations and then point them at a different URL. Most of your handler logic is routing, and that can be done for free with different handlers. But what you're doing is fine - just make sure :

  1. name input fields you need to refer to later
  2. don't compare 'POST' to 'POST', compare the named input field value to the expected value

huangapple
  • 本文由 发表于 2021年12月18日 23:35:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/70404735.html
匿名

发表评论

匿名网友

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

确定