英文:
Problem receiving Axios post data from reactjs app using Golang
问题
我有一个使用ReactJS托管的本地网页,它通过Axios在9000端口发送POST请求。我有一个Golang服务器监听该端口并接收该POST请求。然后,它解码该请求,但是却无法获取其中的任何数据。以下是在ReactJS应用程序中发送Axios POST请求的代码部分。
onSubmit = (event) => {
event.preventDefault();
let { task } = this.state;
console.log("printing new task title:", task);
if (task) {
axios
.post(
endpoint + "/api/task",
{task},
{headers: {"Content-Type": "application/x-www-form-urlencoded"}}
)
.then((res) => {
this.getTasks();
this.setState({task: ""});
console.log(res);
});
}
};
以下是处理该POST请求的Golang服务器代码部分。
// CreateTask create task route
func CreateTask(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Context-Type", "application/x-www-form-urlencoded")
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Methods", "POST")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
var newTask listItem
_ = json.NewDecoder(r.Body).Decode(&newTask)
fmt.Println(newTask)
insertOneTask(newTask)
json.NewEncoder(w).Encode(newTask)
}
以下是listItem结构体的定义。
type listItem struct {
ID primitive.ObjectID `json:"_id,omitempty" bson:"_id,omitempty"`
Title string `json:"title,omitempty"`
Completed bool `json:"completed,omitempty"`
}
我尝试将其重命名为title而不是task,并且只传递静态变量,但都没有成功。
在控制台中,它正确地打印出输入的文本,但是当控制台输出来自Golang服务器的axios响应时,其响应从不包含任务名称。
以下是来自Golang服务器响应的数据部分的示例:data: {_id: '000000000000000000000000', title:'Test'}
。
它只输出data: {_id: '000000000000000000000000'}
。
在接收到POST请求后,Golang终端的输出如下所示:
{ObjectID("000000000000000000000000") false}
Inserted a Single Record ObjectID("63decde2a336b8e7cdc2b865")
似乎新任务的task属性被列为''。我的问题是新任务没有来自网页的输入文本。如果您需要更多代码,请参考以下链接:
英文:
I have a locally hosted webpage using reactjs that sends an Axios post to port 9000. I have a Golang server listening to that port and it recieves the post. It then decodes the post but never gets any of its data. Below is the portion of code that sends the axios post in the reactjs app.
onSubmit = (event) => {
event.preventDefault();
let { task } = this.state;
console.log("printing new task title:", task);
if (task) {
axios
.post(
endpoint + "/api/task",
{task},
{headers: {"Content-Type": "application/x-www-form-urlencoded"}}
)
.then((res) => {
this.getTasks();
this.setState({task: ""});
console.log(res);
});
}
};
The below is the portion of the golang server that handles the post.
// CreateTask create task route
func CreateTask(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Context-Type", "application/x-www-form-urlencoded")
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Methods", "POST")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
var newTask listItem
_ = json.NewDecoder(r.Body).Decode(&newTask)
fmt.Println(newTask)
insertOneTask(newTask)
json.NewEncoder(w).Encode(newTask)
}
Below is the listItem struct
type listItem struct {
ID primitive.ObjectID `json:"_id,omitempty" bson:"_id,omitempty"`
Title string `json:"title,omitempty"`
Completed bool `json:"completed,omitempty"`
}
I've tried renaming it to title instead of task, and just passing in a static variable but to no avail.
In the console it correctly prints the inputed text, but when the console outputs the axios response from the golang server, its response never includes the task name.
This is an example of what the data portion of the response from the golang server should look like: data: {_id: '000000000000000000000000', title:'Test'}
.
It only ever outputs this data: {_id: '000000000000000000000000'}
The golang terminal output after the post is recieved is as follows:
{ObjectID("000000000000000000000000") false}
Inserted a Single Record ObjectID("63decde2a336b8e7cdc2b865")
It seems the task attribute is listed as '' in the new . My problem is the new task doesn't have the inputted text from the webpage. If you need more of the code it's below
答案1
得分: 1
建议使用DevTools来调试这种问题。
截图显示payload是form-url-encoded格式。但是服务器尝试使用json解码器(_ = json.NewDecoder(r.Body).Decode(&newTask)
)来读取它。如果不忽略Decode
的错误,它应该会报告内容不是有效的json。要解决此问题,只需从client/src/To-Do-List.js
中删除{headers: {"Content-Type": "application/x-www-form-urlencoded"}}
。
更改后,payload将变为:
其他错误:
1. Context-Type
头与响应中的内容不匹配
go-server/main.go
中的CreateTask
函数还有另一个问题。响应被编码为json:
json.NewEncoder(w).Encode(newTask)
这与以下代码冲突:
w.Header().Set("Context-Type", "application/x-www-form-urlencoded")
应将头替换为:
w.Header().Set("Context-Type", "application/json")
2. CORS设置不正确
r.HandleFunc("/api/task", GetAllTasks).Methods("GET", "OPTIONS")
r.HandleFunc("/api/task", CreateTask).Methods("POST", "OPTIONS")
OPTIONS
请求将由GetAllTasks
处理。为了允许POST请求中的Content-Type
头,应将以下行添加到GetAllTasks
中:
w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
由于CreateTask
不处理OPTIONS
请求,因此可以删除以下行:
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Methods", "POST")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
英文:
It's recommended to use DevTools to debug such kind of problem.
The screenshot shows that the payload is form-url-encoded. But the server tries to read it with a json decoder (_ = json.NewDecoder(r.Body).Decode(&newTask)
). If you do not ignore the error from Decode
, it should report that the content is not a valid json. To fix the issue, just remove {headers: {"Content-Type": "application/x-www-form-urlencoded"}}
from client/src/To-Do-List.js
.
After the change, the payload will be:
Other errors:
1. Context-Type
header does not match the content in the response
The func CreateTask
in go-server/main.go
has another issue too. The response is encoded as json:
json.NewEncoder(w).Encode(newTask)
Which conflicts with:
w.Header().Set("Context-Type", "application/x-www-form-urlencoded")
The header should be replaced with:
w.Header().Set("Context-Type", "application/json")
2. The CORS is not set correctly
r.HandleFunc("/api/task", GetAllTasks).Methods("GET", "OPTIONS")
r.HandleFunc("/api/task", CreateTask).Methods("POST", "OPTIONS")
The OPTIONS
requests will be handled by GetAllTasks
. In order to allow the Content-Type
header in the POST request, the following line should be added to GetAllTasks
:
w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
And since CreateTask
does not handle the OPTIONS
request, the following lines can be removed:
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Methods", "POST")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论