How can you read POST data from a javascript XMLHttpRequest in Golang?

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

How can you read POST data from a javascript XMLHttpRequest in Golang?

问题

以下是翻译好的内容:

这是一个名为cwk_submit_form的JavaScript函数:

function cwk_submit_form() {
   var form = document.getElementById("FORM_ID");
   var XHR = new XMLHttpRequest();

   const FD = new FormData(form);
   for (const element of FD.entries()) {
       console.log(element);
   }

   XHR.open("POST", "http://localhost:8080/post_data");
   XHR.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

   XHR.send(FD);
}

我在这里留下了console.log,以说明这会打印出正确的数据,这意味着问题似乎出在数据传输上。

接收响应的Golang代码如下:

func post_data(w http.ResponseWriter, r *http.Request) {
    log.Println("post was called")

    r.ParseForm()
    for key, value := range r.Form {
        log.Printf("%s = %s\n", key, value)
    }
}

这个for循环没有打印任何内容。

如果我使用HTML表单进行提交,如下所示:

<form action="//localhost:8080/post_data" method="POST">
    <input type="text" name="field1" value="" maxLength="20"/>
    <input type="text" name="field2" value="" maxLength="20"/>
    <input type="submit" value="Sign in"/>
</form>

那么上面的Golang代码就可以正常工作,这让我相信问题出在XMLHttpRequest的格式上。

英文:

Here's the javascript function called:

function cwk_submit_form() {
   var form = document.getElementById(&quot;FORM_ID&quot;)
   var XHR = new XMLHttpRequest();


   const FD = new FormData( form );
   for (const element of FD.entries()) {
       console.log(element)
   }

   XHR.open( &quot;POST&quot;, &quot;http://localhost:8080/post_data&quot; );
   XHR.setRequestHeader(&quot;Content-Type&quot;, &quot;application/x-www-form-urlencoded&quot;);

   XHR.send( FD );
}

I left the console.log in there to mention that this does print out the correct data, meaning that the issue is seems to be in how the data is transferred.

The Golang code that receives the response is:

func post_data(w http.ResponseWriter, r *http.Request) {
	log.Println(&quot;post was called&quot;)

	r.ParseForm()
	for key, value := range r.Form {
		log.Printf(&quot;%s = %s\n&quot;, key, value)
	}
}

Nothing is printed by this for loop.

If I use an HTML Form to submit like so:

&lt;form action=&quot;//localhost:8080/post_data&quot; method=&quot;POST&quot;&gt;
	&lt;input type=&quot;text&quot; name=&quot;field1&quot; value=&quot;&quot; maxLength=&quot;20&quot;/&gt;
		
	&lt;input type=&quot;text&quot; name=&quot;field2&quot; value=&quot;&quot; maxLength=&quot;20&quot;/&gt;
		
	&lt;input type=&quot;submit&quot; value=&quot;Sign in&quot;/&gt;
&lt;/form&gt;

then the Golang code above works fine, which leads me to believe that the XMLHttpRequest format is the issue.

答案1

得分: 1

你的猜测是正确的,你的js代码有问题。

> 对于所有的请求,ParseForm会解析URL中的原始查询并更新r.Form。

因此,只有当你发送的Content-Type和实际的内容类型匹配为application/x-www-form-urlencoded时,它才能正常工作,这在你的HTML表单情况下是成立的。

另一方面,当你使用FormData时,它将以multipart/form-data的形式发送。

你需要将XHR.send(FD)替换为XHR.send(new URLSearchParams(FD)),以便以application/x-www-form-urlencoded的形式发送数据。

英文:

Your guess is right there is a problem in your js code.

> For all requests, ParseForm parses the raw query from the URL and updates r.Form.

And hence, it will work when the Content-Type you send and the actual content type matches to application/x-www-form-urlencoded which happens in your HTML form case.

On the other hand, when you use FormData, it will be sent as multipart/form-data.

You need to replace your XHR.send(FD) with XHR.send(new URLSearchParams(FD)) in order to send the data in application/x-www-form-urlencoded.

huangapple
  • 本文由 发表于 2022年5月15日 05:26:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/72243964.html
匿名

发表评论

匿名网友

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

确定