What I want to do
I am creating a Todo app for my Golang studies. I would like to read the data from POST requests in React with Golang.
Code
go Backend
package todos
import (
"database/sql"
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"os"
"strings"
"time"
"todo-app/auth"
"github.com/joho/godotenv"
)
type Todo struct {
// UserID int `json:"userid"`
Todo string `json:"todo"`
CreatedAt time.Time `json:"createdat"`
UpdatedAt time.Time `json:"updatedat"`
}
type TodoBody struct {
Todo string `json:"todo"`
}
func CreateTodo(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "*")
w.Header().Set("Access-Control-Allow-Origin", "http://localhost:3000")
w.Header().Set("Access-Control-Allow-Credentials", "true")
w.Header().Set("Access-Control-Allow-Headers", "*")
e := godotenv.Load()
if e != nil {
log.Fatal(e)
}
dbConnectionInfo := fmt.Sprintf("%s:%s@tcp(127.0.0.1:3306)/go_todo", os.Getenv("DB_USER"), os.Getenv("DB_PASSWORD"))
db, err := sql.Open("mysql", dbConnectionInfo)
if err != nil {
log.Fatal(err)
}
defer db.Close()
tokenString := r.Header.Get("Authorization")
tokenString = strings.TrimPrefix(tokenString, "Bearer ")
log.Printf("request token=%s\n", tokenString)
body, err := ioutil.ReadAll(r.Body)
if err != nil {
log.Fatal(err)
}
log.Printf("request body=%s\n", body)
var data TodoBody
if err := json.Unmarshal(body, &data); err != nil {
log.Println(err)
}
// userId := 12
todo := data.Todo
todoData := Todo{todo, time.Now(), time.Now()}
_, err2 := auth.TokenVerify(tokenString)
if err2 != nil {
log.Fatal(err)
} else {
stmt, err := db.Prepare("INSERT INTO todos (Todo,CreatedAt,UpdatedAt) VALUES(?,?,?)")
if err != nil {
log.Fatal(err)
}
_, err = stmt.Exec(todoData.Todo, todoData.CreatedAt, todoData.UpdatedAt)
if err != nil {
log.Fatal(err)
}
json.NewEncoder(w).Encode(todoData)
}
}
React Frontend
import { useState } from "react";
import { useCreateTodo } from "../../hooks/useCreateTodo";
import { BaseButton } from "../atoms/baseButton";
import { TextArea } from "../atoms/textArea";
export const AddTodo = () => {
const [text, setText] = useState("");
const CreateTodo = useCreateTodo();
const token = "Bearer " sessionStorage.getItem("token");
const onClickCreate = () => {
CreateTodo(token, text);
};
return (
<div>
<TextArea
onChange={(e: any) => setText(e.target.value)}
defaultValue=""
/>
<BaseButton text="タスクを追加" onClick={onClickCreate} />
</div>
);
};
POST here ↓
import axios from "axios";
export const useCreateTodo = () => {
const CreateTodo = (token: string, todo: any) => {
const URL = "http://127.0.0.1:8080/createtodo";
const data = { todo: todo };
console.log(data);
axios
.post(URL, JSON.stringify(data), { headers: { Authorization: token } })
.then((res) => console.log(res))
.catch((err) => console.log(err));
};
return CreateTodo;
};
If I don't add a header when POST the correct value comes to Go's ioutil.ReadAll(r.Body), but if I add a header, I can't get the value. When I hit Go's API with the Advanced REST client, it is processed correctly even with the header information, so I am wondering if there is a problem with the POST method, but I can't seem to solve the problem. I would be grateful for your help. Best regards.
CodePudding user response:
I added this code and it solved the problem..
w.Header().Set("Access-Control-Allow-Origin", "http://localhost:3000")
switch r.Method {
case "OPTIONS":
w.Header().Set("Access-Control-Allow-Headers", "*")
w.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
return
Thanks for your cooperation!