在Golang中转发POST请求数据

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

Forwarding POST request data in Golang

问题

我有一个AJAX的POST请求,将会发送到Golang后端。目标是在将请求发送到外部API端点之前编辑此请求。

AJAX的POST请求示例:

var ajaxParams = {
    type: 'POST',
    url: '/golang_endpoint', // Golang后端端点
    dataType: 'json',
    data: encodeURIComponent(JSON.stringify(request)), // 这是我们要发送到外部端点的表单
    success: onResponse,
    error: onError,
};
$.ajax(ajaxParams);

这个请求将会触发相关的Golang处理程序,我们希望在发送请求之前编辑一些请求内容。然而,我们在发送请求时遇到了错误,即使没有进行任何编辑:

func golangEndpointHandler(rw http.ResponseWriter, req *http.Request) {
    fmt.Println(req.PostForm)
    resp, err := http.PostForm("webwsite.com/outside/endpoint", req.PostForm)
}

具体来说,我们在发送POST请求时遇到了500内部服务器错误(例如:unexpected token at '=')。使用req.PostForm来转发请求数据是否正确?错误提示可能是与对req.PostForm或AJAX数据参数的解码/编码有关吗?

打印语句表明进行了JSON序列化:
map[{"size":"1000","other_data":12345}:[]]

编辑:根据@belindamichaels的回答。
我认为ParseForm执行了某种编码/解码操作,导致一旦发送到外部端点就会出现500错误响应。

以下组合是有效的:

var ajaxParams = {
    type: 'POST',
    url: '/golang_endpoint',
    dataType: 'json',
    processData: false,
    timeout: timeout,
    data: encodeURIComponent(JSON.stringify(request)),
    success: onResponse,
    error: onError,
};
resp, err := http.Post("webwsite.com/outside/endpoint", req.Header.Get("Content-Type"), req.Body)

但以下组合无效:

var ajaxParams = {
    type: 'POST',
    url: '/golang_endpoint',
    dataType: 'json',
    processData: false,
    timeout: timeout,
    data: request, // 未进行字符串化或URL编码
    success: onResponse,
    error: onError,
};
req.ParseForm()
resp, err := http.PostForm("webwsite.com/outside/endpoint", req.PostForm)

尽管没有编辑请求,我们仍然遇到500错误(具体为unexpected token at 'object Object]=')。在准备发送到外部端点时,如何对数据进行字符串化和URL编码?

注意:以下组合也不起作用:

var ajaxParams = {
    type: 'POST',
    url: '/golang_endpoint',
    dataType: 'json',
    processData: false,
    timeout: timeout,
    data: encodeURIComponent(JSON.stringify(request)), // 这个改变
    success: onResponse,
    error: onError,
};
req.ParseForm()
resp, err := http.PostForm("webwsite.com/outside/endpoint", req.PostForm)

我们得到了类似的500错误:unexpected token at '='

英文:

I have an AJAX post request that will hit the Golang backend. The goal is to edit this request before sending the request to an outside api endpoint.

The ajax POST request example:

    var ajaxParams = {
    type: 'POST',
    url: '/golang_endpoint', // golang backend endpoint
    dataType: 'json',
    data: encodeURIComponent(JSON.stringify(request)), // this is the form we want to send to an external endpoint
    success: onResponse,
    error: onError,
};
$.ajax(ajaxParams);

This request will hit the associated Golang handler, and we want to edit some of the request before sending it out. However, we are getting errors just sending the request without any edits:

func golangEndpointHandler(rw http.ResponseWriter, req *http.Request) {
    fmt.Println(req.PostForm)
	resp, err := http.PostForm("webwsite.com/outside/endpoint", req.PostForm)
}

Specifically, we are getting 500 Internal Server Errors sending the POST request (ex: unexpected token at '='). Is using req.PostForm the right way to forward our request data? The error indicates maybe something with decoding/encoding req.PostForm or the data from the AJAX data param?

The print statement suggests a json serialization was performed:
map[{"size":"1000","other_data":12345}:[]]

EDIT: per @belindamichaels response.
I believe ParseForm does some sort of encoding/decoding that causes 500 responses once sent to the outside endpoint.

While this combination works:

var ajaxParams = {
    type: 'POST',
    url: '/golang_endpoint'
    dataType: 'json',
    processData: false,
    timeout: timeout,
    data: encodeURIComponent(JSON.stringify(request)),
    success: onResponse,
    error: onError,
};
resp, err := http.Post("webwsite.com/outside/endpoint", req.Header.Get("Content-Type"), req.Body)

This does not:

var ajaxParams = {
    type: 'POST',
    url: '/golang_endpoint'
    dataType: 'json',
    processData: false,
    timeout: timeout,
    data: request, // not stringified or url-encoded
    success: onResponse,
    error: onError,
};
req.ParseForm()
resp, err := http.PostForm("webwsite.com/outside/endpoint", req.PostForm)

Despite no editing of the request, we are getting 500's (specifically unexpected token at 'object Object]='). How can I stringify and urlencode the data once ready to send to the outside endpoint?

NOTE: the following combination also does not work:

var ajaxParams = {
    type: 'POST',
    url: '/golang_endpoint'
    dataType: 'json',
    processData: false,
    timeout: timeout,
    data: encodeURIComponent(JSON.stringify(request)), // the change
    success: onResponse,
    error: onError,
};
req.ParseForm()
resp, err := http.PostForm("webwsite.com/outside/endpoint", req.PostForm)

We get a similar 500 error: unexpected token at '='

答案1

得分: 1

要将请求原样转发,请使用以下代码:

resp, err := http.Post("webwsite.com/outside/endpoint", req.Header.Get("Content-Type"), req.Body)

如果您想编辑请求体,服务器和客户端必须就请求体的类型达成一致。以下是如何使用application/x-www-form-urlencoded的示例。将表单原样传递给服务器,不要像问题中那样将表单编码为JSON。

var ajaxParams = {
    type: 'POST',
    url: '/golang_endpoint', // golang后端端点
    dataType: 'json',
    data: request,
    success: onResponse,
    error: onError,
};

在服务器上解析表单,进行编辑并发送。

req.ParseForm()
// 编辑表单
resp, err := http.PostForm("webwsite.com/outside/endpoint", req.PostForm)
英文:

To forward the request as is, use:

resp, err := http.Post("webwsite.com/outside/endpoint", req.Header.Get("Content-Type"), req.Body)

If you want to edit the request body, the server and client must agree on the type of the request body. Here's how to use application/x-www-form-urlencoded. Pass the form as is to the server. Don't encode the form as JSON as in the question.

    var ajaxParams = {
    type: 'POST',
    url: '/golang_endpoint', // golang backend endpoint
    dataType: 'json',
    data: request,
    success: onResponse,
    error: onError,
};

Parse the form on the server, edit it and send it on.

req.ParseForm()
// edit form
resp, err := http.PostForm("webwsite.com/outside/endpoint", req.PostForm

huangapple
  • 本文由 发表于 2023年2月1日 01:05:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/75300608.html
匿名

发表评论

匿名网友

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

确定