如何将包含一些数据的GET请求重定向到POST请求?

时间:2018-10-30 03:05:48

标签: go

当用户使用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.

3 个答案:

答案 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)

很不幸,我不认为重定向可以更改动词(例如GETPOST)或向请求中添加数据。它只能更改URL。

有关更多信息,请参见Redirect ()

答案 2 :(得分:0)

我从未听说过将动词从GET更改为POST。我猜这是不可能的,因为POST假定身体为身体(但是可能为空),而GET不是。因此,在一般情况下,浏览器将无法从无到有。 否则有可能:您可以在发布后发送302重定向,以使浏览器执行get。动词也可以保留307个回复代码。

尝试重新考虑浏览器与服务器的交互。也许您可以将POST重定向到另一个位置来解决任务?