go - 如何将 GET 请求重定向到包含一些数据的 POST 请求?
问题描述
当用户使用 GET 请求点击某个 url 时,我想将他们重定向到另一个位置的 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.
解决方案
HTTP 重定向(即回复状态码为 301、302、307,308 和Location
标头)只能将现有请求重定向到另一个位置,而不会更改请求的负载。不过,它可以在响应标头中添加一些 cookie。
为了自动将 GET 请求更改为具有特定负载的 POST 请求,您可能会尝试向客户端发送带有 a 的 HTML 页面<form method=POST...
和带有隐藏输入字段的负载,即<input name=... value=... type=hidden>
,然后将一些 JavaScript 添加到自动提交表单的页面. 但是这种黑客只能在浏览器中使用,并且只有在启用 JavaScript 的情况下才能使用,并且也不适用于所有类型的有效负载。
为了与更广泛的客户端保持兼容性,最好进行不同的设计,即将 GET 请求保留在重定向中,但将必要的有效负载作为参数提供给新目标,即http://new.target/foo?payload=....
. 但细节取决于请求的目标可以处理什么。
推荐阅读
- tensorflow - TensorFlow lite:将模型转换为 tflite 后精度损失很大
- vue.js - 多个 v-for 在一行上
- typescript - TypeScript - 基于泛型类型的条件函数
- python - Python正则表达式获取所有内容,直到像''(year)'这样的表达式
- python - 如何使用 pipenv 运行 --upgrade?
- php - 序号联系表 7
- babeljs - babel v7 的 `babel-plugin-module-resolver` 的替代品是什么?
- java - JAXB JavaTypeAdapter 不工作
- matlab - 在 MATLAB 中为二维数组中的字段赋值
- javascript - 如何从另一个父类方法调用父类方法