英文:
Sending a JSON object to a Go server from a webpage
问题
我正在尝试将一个JSON对象发送到我的Go服务器。我查看了所有我能找到的示例,但无法弄清楚我漏掉了什么。
服务器代码如下:
package main
import (
"fmt"
"io/ioutil"
"log"
"net/http"
"text/template"
)
func handler(w http.ResponseWriter, r *http.Request) {
t, err := template.ParseFiles("list.html")
if err != nil {
fmt.Println("Failed to parse")
log.Fatal(err)
}
m := make(map[string]string)
m["Title"] = "A title"
err = t.Execute(w, m)
if err != nil {
fmt.Println("Failed to execute")
log.Fatal(err)
}
}
func getRes(w http.ResponseWriter, r *http.Request) {
fmt.Println("HEADER: ", r.Header)
fmt.Println("CL: ", r.ContentLength)
fmt.Println("CT: ", r.Header.Get("Content-Type"))
b, err := ioutil.ReadAll(r.Body)
if err != nil {
log.Fatal(err)
}
fmt.Println("B: ", string(b))
}
func main() {
fmt.Println("Starting")
http.HandleFunc("/", handler)
http.HandleFunc("/getRes/", getRes)
log.Fatal(http.ListenAndServe(":8080", nil))
}
当我使用curl时,它可以正常工作。
curl --header "Content-Type: application/json" -d "{\"rating\":3}" http://localhost:8080/getRes/
我得到以下响应:
HEADER: map[Accept:[*/*] Content-Length:[12] Content-Type:[application/json] User-Agent:[curl/7.58.0]]
CL: 12
CT: application/json
B: {"rating":3}
但是,当我使用以下HTML/JavaScript代码时,它不起作用:
<html>
<head>
<script>
window.onload = function() {
fetch("getRes", {
"method": "POST",
"body": JSON.stringify({
"rating": 5
}),
"headers": {
"Content-type": "application/json"
}
});
}
</script>
</head>
<body>
{{.Title}}
</body></html>
我得到一个响应,但它是空的,内容长度为零:
HEADER: map[Accept:[*/*] Accept-Encoding:[gzip, deflate, br] Accept-Language:[en-GB,en-US;q=0.9,en;q=0.8] Connection:[keep-alive] Referer:[http://localhost:8080/] Sec-Fetch-Mode:[cors] Sec-Fetch-Site:[same-origin] User-Agent:[Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36]]
CL: 0
CT:
B:
英文:
I'm trying to send a JSON object to my Go server. I've looked at all the examples I could find and can't figure out what I'm missing.
The server code:
package main
import (
"fmt"
"io/ioutil"
"log"
"net/http"
"text/template"
)
func handler(w http.ResponseWriter, r *http.Request) {
t, err := template.ParseFiles("list.html")
if err != nil {
fmt.Println("Failed to parse")
log.Fatal(err)
}
m := make(map[string]string)
m["Title"] = "A title"
err = t.Execute(w, m)
if err != nil {
fmt.Println("Failed to execute")
log.Fatal(err)
}
}
func getRes(w http.ResponseWriter, r *http.Request) {
fmt.Println("HEADER: ", r.Header)
fmt.Println("CL: ", r.ContentLength)
fmt.Println("CT: ", r.Header.Get("Content-Type"))
b, err := ioutil.ReadAll(r.Body)
if err != nil {
log.Fatal(err)
}
fmt.Println("B: ", string(b))
}
func main() {
fmt.Println("Starting")
http.HandleFunc("/", handler)
http.HandleFunc("/getRes/", getRes)
log.Fatal(http.ListenAndServe(":8080", nil))
}
This works when I use curl.
curl --header "Content-Type: application/json" -d "{\"rating\":3}" http://localhost:8080/getRes/
I get the response:
HEADER: map[Accept:[*/*] Content-Length:[12] Content-Type:[application/json] User-Agent:[curl/7.58.0]]
CL: 12
CT: application/json
B: {"rating":3}
It doesn't work when I use the following HTML/Javascript code:
<html>
<head>
<script>
window.onload = function() {
fetch("getRes", {
"method": "POST",
"body": JSON.stringify({
"rating": 5
}),
"headers": {
"Content-type": "application/json"
}
});
}
</script>
</head>
<body>
{{.Title}}
</body></html>
I get a response but it's empty with a content length of zero:
HEADER: map[Accept:[*/*] Accept-Encoding:[gzip, deflate, br] Accept-Language:[en-GB,en-US;q=0.9,en;q=0.8] Connection:[keep-alive] Referer:[http://localhost:8080/] Sec-Fetch-Mode:[cors] Sec-Fetch-Site:[same-origin] User-Agent:[Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36]]
CL: 0
CT:
B:
答案1
得分: 2
页面将数据以POST方式提交到路径/getres
。由于没有为/getres
注册处理程序,但为/getres/
注册了处理程序,所以mux将客户端重定向到/getres/
。重定向是一个没有请求体的GET请求。
ServeMux文档描述了重定向的行为:
> 如果已经注册了一个子树,并且收到了一个请求,请求中的路径是子树根路径但没有尾部斜杠,ServeMux会将该请求重定向到子树根路径(添加尾部斜杠)。
修复方法是为路径/getres
注册处理程序:
http.HandleFunc("/getRes", getRes)
或者将数据以POST方式提交到路径/getRes/
:
fetch("getRes/", {
英文:
The page POSTs to the path /getres
. The mux redirects the client to /getres/
because there is not a handler for registered for /getres
, but there is for /getres/
. The redirect is a GET request with no body.
The ServeMux documentation describes the redirect:
> If a subtree has been registered and a request is received naming the subtree root without its trailing slash, ServeMux redirects that request to the subtree root (adding the trailing slash).
Fix by registering the handler for the path /getres
http.HandleFunc("/getRes", getRes)
or by posting to the path /getRes/
:
fetch("getRes/", {
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论