处理CORS表单提交

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

Handling CORS form submissions

问题

我有一个非常简单的表单,从localhost:3000提供。

<!-- language: html -->

&lt;form id=&quot;my-HTML-form&quot; action=&quot;http://localhost:8080&quot; method=&quot;POST&quot;&gt;
    &lt;input type=&quot;text&quot; placeholder=&quot;用户名&quot; name=&quot;username&quot; /&gt;
    &lt;input type=&quot;password&quot; placeholder=&quot;密码&quot; name=&quot;password&quot; /&gt;
    &lt;input type=&quot;hidden&quot; name=&quot;form-id&quot; value=&quot;login&quot; /&gt;
    &lt;button type=&quot;submit&quot;&gt;提交&lt;/button&gt;
&lt;/form&gt;

在localhost:8080上,我有一个非常简单的Go服务器:
<!-- language: Go -->

package main

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

func main() {
	// 启动服务器
	http.HandleFunc(&quot;/&quot;, handler)
	serverErr := http.ListenAndServe(&quot;:8080&quot;, nil)
	if serverErr != nil {
		log.Println(&quot;启动服务器时出错&quot;)
		log.Fatal(serverErr)
	}
}

func handler(w http.ResponseWriter, r *http.Request) {
	log.Println(r.Header.Get(&quot;Origin&quot;))
	log.Println(r.Method)

    w.Header().Set(&quot;Access-Control-Allow-Origin&quot;, &quot;*&quot;)
    w.Header().Set(&quot;Access-Control-Allow-Methods&quot;, &quot;GET, POST, OPTIONS&quot;)
    w.Header().Set(&quot;Access-Control-Allow-Headers&quot;,
	&quot;Accept, Accept-Encoding, Authorization, Content-Length, Content-Type, Origin, X-CSRF-Token&quot;)
    w.WriteHeader(http.StatusOK)
}

当我提交表单时,实际上会收到两个请求!一个是POST请求,一个是GET请求!这是我在单次提交后的控制台输出:

$ http://localhost:3000
$ POST
$ 
$ GET

请注意,GET请求没有附加来源。我想执行一些逻辑,然后根据成功或失败将用户重定向到不同的URL。但是我无法做到这一点,因为GET请求紧随POST请求之后。我可以使用AJAX,没有问题,但我希望找到一个简单的HTML表单提交的解决方案。

有什么想法、建议吗?所有的浏览器都遵循POST/Redirect/Get范例吗?谢谢。

英文:

I have a very simple form being served from localhost:3000

<!-- language: html -->

&lt;form id=&quot;my-HTML-form&quot; action=&quot;http://localhost:8080&quot; method=&quot;POST&quot;&gt;
    &lt;input type=&quot;text&quot; placeholder=&quot;Username&quot; name=&quot;username&quot; /&gt;
    &lt;input type=&quot;password&quot; placeholder=&quot;Password&quot; name=&quot;password&quot; /&gt;
    &lt;input type=&quot;hidden&quot; name=&quot;form-id&quot; value=&quot;login&quot; /&gt;
    &lt;button type=&quot;submit&quot;&gt;Submit&lt;/button&gt;
&lt;/form&gt;

On localhost:8080, I have a very simple go server:
<!-- language: Go -->

package main

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

func main() {
	// Start the server
	http.HandleFunc(&quot;/&quot;, handler)
	serverErr := http.ListenAndServe(&quot;:8080&quot;, nil)
	if serverErr != nil {
		log.Println(&quot;Error starting server&quot;)
		log.Fatal(serverErr)
	}
}

func handler(w http.ResponseWriter, r *http.Request) {
	log.Println(r.Header.Get(&quot;Origin&quot;))
	log.Println(r.Method)
	
    w.Header().Set(&quot;Access-Control-Allow-Origin&quot;, &quot;*&quot;)
    w.Header().Set(&quot;Access-Control-Allow-Methods&quot;, &quot;GET, POST, OPTIONS&quot;)
    w.Header().Set(&quot;Access-Control-Allow-Headers&quot;,
	&quot;Accept, Accept-Encoding, Authorization, Content-Length, Content-Type, Origin, X-CSRF-Token&quot;)
    w.WriteHeader(http.StatusOK)
}

When I submit my form, I actually receive two requests! A POST and a GET! Here is my console after a SINGLE submit:

$ http://localhost:3000
$ POST
$ 
$ GET

Notice the GET request doesn't have an origin attached to it. I'm trying to perform some logic and then redirect the user to different url's based on success or failure. But I can't do this because the GET request immediately follows the POST request. I can use AJAX, no problem, but I was hoping to find a solution for a simple html form submission.

Any thoughts, ideas? Do all browsers follow the POST/Redirect/Get paradigm and I'm SOL?

Thanks.

答案1

得分: 1

我假设你的表单操作是 action=&quot;http://localhost:8080&quot;,因为你说这是一个跨域请求。

第二个GET请求是对favicon的请求(正如elithrar在评论中指出的)。只需执行log.Println(r.URL)以确保。虽然我不确定为什么浏览器没有添加origin头。

你可以通过将w.WriteHeader(http.StatusOK)替换为例如http.Redirect(w, r, &quot;http://localhost:3000/success.html&quot;, http.StatusSeeOther)来重定向请求。

英文:

I assume your form action is action=&quot;http://localhost:8080&quot; because you said this is a cross origin request.

The second GET request is the request for favicon (as elithrar points out in comments). Just do a log.Println(r.URL) to make sure. I am not sure why the browser does not add origin header to it though.

You can redirect requests by replacing w.WriteHeader(http.StatusOK) by for example,
http.Redirect(w, r, &quot;http://localhost:3000/success.html&quot;, http.StatusSeeOther).

huangapple
  • 本文由 发表于 2016年3月17日 08:54:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/36049766.html
匿名

发表评论

匿名网友

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

确定