当用户使用GET请求访问某个网址时,我想将其重定向到另一个位置的POST请求。
package main
import (
"bytes"
"fmt"
"io/ioutil"
"log"
"net/http"
"net/url"
)
func old(w http.ResponseWriter, r *http.Request) {
newURL := "/new"
var bdy = []byte(`title=Buy cheese and bread for breakfast.`)
r.Method = "POST"
r.URL, _ = url.Parse(newURL)
r.RequestURI = newURL
r.Body = ioutil.NopCloser(bytes.NewReader(bdy))
r.Header.Set("Content-Type", "application/x-www-form-urlencoded")
http.Redirect(w, r, newURL, 302)
}
func new(w http.ResponseWriter, r *http.Request) {
r.ParseForm()
fmt.Printf("Method:%v\n", r.Method)
fmt.Printf("Title:%v\n", r.Form.Get("title"))
}
func main() {
http.HandleFunc("/", old)
http.HandleFunc("/new", new)
port := 8000
fmt.Printf("listening on %v\n", port)
if err := http.ListenAndServe(fmt.Sprintf(":%v", port), nil); err != nil {
log.Fatal("ListenAndServe: ", err)
}
}
当我点击“ /”时,我最终被重定向到“ / new”,但是收到了GET请求,但没有表单数据:
Method:GET
Title:
如果我直接卷曲“ / new”,我会得到:
curl -XPOST localhost:8000/new -d "title=Buy cheese and bread for breakfast."
Method:POST
Title:Buy cheese and bread for breakfast.
答案 0 :(得分:3)
HTTP重定向(即以状态代码301、302、307,308和<form method=POST...
标头答复)只能将现有请求重定向到另一个位置,而不能更改请求的有效负载。它可以在响应头中添加一些cookie。
为了自动将具有特定有效负载的GET请求更改为POST请求,您可以尝试向客户端发送带有<input name=... value=... type=hidden>
的HTML页面和具有隐藏输入字段(即http://new.target/foo?payload=....
)的有效负载然后将一些JavaScript添加到自动提交表单的页面。但是,只有在启用了JavaScript的情况下,这种黑客攻击才会在浏览器中起作用,并且也不适用于所有类型的有效载荷。
要保持与更广泛客户端的兼容性,最好进行不同的设计,即将GET请求保留在重定向中,但将必要的有效负载作为参数提供给新目标,即{{1}}。但是详细信息取决于请求目标可以处理的内容。
答案 1 :(得分:2)
很不幸,我不认为重定向可以更改动词(例如GET
,POST
)或向请求中添加数据。它只能更改URL。
有关更多信息,请参见Redirect ()。
答案 2 :(得分:0)
我从未听说过将动词从GET更改为POST。我猜这是不可能的,因为POST假定身体为身体(但是可能为空),而GET不是。因此,在一般情况下,浏览器将无法从无到有。 否则有可能:您可以在发布后发送302重定向,以使浏览器执行get。动词也可以保留307个回复代码。
尝试重新考虑浏览器与服务器的交互。也许您可以将POST重定向到另一个位置来解决任务?