Le côté client (React / axios.post) n'a pas pu publier sur l'API côté serveur (Golang / gin) avec le code d'état 404. Je veux que cette demande de publication soit réussie.
Suite au succès de curl pour écrire des données dans la table mysql
OPTIONS http://localhost:4000/api/post 404 (Not Found) Access to XMLHttpRequest at 'http://localhost:4000/api/post' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. createError.js:17 Uncaught (in promise) Error: Network Error at createError (createError.js:17) at XMLHttpRequest.handleError (xhr.js:80)
Mais, dans le cas de axios.post, une erreur 404 se produit. / p>
Ceci est le code source cible.
type Article struct { ID int `json:"id"` TITLE string `json:"title"` CONTENT string `json:"content"` } var articles []Article func main() { db, err := sql.Open("mysql", "user:password@tcp(localhost:3306)/article") if err != nil { panic(err.Error()) } defer db.Close() router := gin.Default() api := router.Group("/api") { api.POST("/post", func(c *gin.Context) { var article Article c.BindJSON(&article) c.Header("Content-Type", "application/json") c.Header("Access-Control-Allow-Origin", "*") ins, err := db.Prepare("INSERT INTO articles(title,content) VALUES(?,?)") if err != nil { log.Fatal(err) } ins.Exec(article.TITLE, article.CONTENT) c.JSON(http.StatusOK, gin.H{"status": "ok"}) }) } router.Run(":4000") }
interface ArticleState { title: string; content: string; redirect: boolean; } class Post extends React.Component<{}, ArticleState> { constructor(props: {}) { super(props); this.state = { title: '', content: '', redirect: false, }; this.handleChangeTitle = this.handleChangeTitle.bind(this); this.handleChangeContent = this.handleChangeContent.bind(this); this.setRedirect = this.setRedirect.bind(this); this.renderRedirect = this.renderRedirect.bind(this); } handleChangeTitle(e: React.FormEvent<HTMLInputElement>) { this.setState({title: e.currentTarget.value}); } handleChangeContent(e: React.FormEvent<HTMLInputElement>) { this.setState({content: e.currentTarget.value}); } setRedirect() { this.setState({ redirect: true, }); const data = {title: this.state.title, content: this.state.content}; axios.post('http://localhost:4000/api/post', data).then(res => { console.log(res); }); } renderRedirect = () => { if (this.state.redirect) { return <Redirect to="/post/finish" />; } }; render() { return ( <Container text style={{marginTop: '3em'}}> <Form onSubmit={this.setRedirect}> <Form.Input label="Title" name="title" value={this.state.title} onChange={this.handleChangeTitle} /> <Form.Field label="Content" name="content" value={this.state.content} control="textarea" onChange={this.handleChangeContent} /> {this.renderRedirect()} <Form.Button content="Submit" /> </Form> </Container> ); } }
Je m'attends à ce que axios.post réussisse à demander, mais en fait a échoué avec le statut 404 .
curl -X POST -H "Content-Type: application/json" -d '{"title":"bbb", "content":"bbb"}' localhost:4000/api/post
3 Réponses :
Comme l'erreur indique que la requête "a été bloquée par la stratégie CORS", qui est l'abréviation de " Partage de ressources inter-origines 'et est une mesure de sécurité implémentée par le navigateur. La solution consiste à modifier votre serveur pour renvoyer l’en-tête «Access-Control-Allow-Origin» correct.
J'ai déjà ajouté c.Header ("Access-Control-Allow-Origin", "*")
dans le code côté serveur. Mais toujours la même erreur se produit.
Après avoir ajouté quelques codes côté serveur, le problème a été résolu.
api.POST("/post", func(c *gin.Context) { c.Header("Content-Type", "application/json") c.Header("Access-Control-Allow-Origin", "*") // add c.Header("Access-Control-Allow-Headers", "Content-Type") var article Article c.BindJSON(&article) ins, err := db.Prepare("INSERT INTO articles(title,content) VALUES(?,?)") if err != nil { log.Fatal(err) } ins.Exec(article.TITLE, article.CONTENT) c.JSON(http.StatusOK, gin.H{"status": "ok"}) }) // add response to OPTIONS api.OPTIONS("/post", func(c *gin.Context) { c.Header("Content-Type", "application/json") c.Header("Access-Control-Allow-Origin", "*") c.Header("Access-Control-Allow-Headers", "Content-Type") c.JSON(http.StatusOK, gin.H{"status": "ok"}) })
Voici le code de travail que j'ai testé:
type Article struct { ID int `json:"id"` TITLE string `json:"title"` CONTENT string `json:"content"` } var articles []Article func main() { db, err := sql.Open("mysql", "root:111111@tcp(localhost:3306)/article") if err != nil { panic(err.Error()) } defer db.Close() router := gin.Default() router.Use(cors.New(cors.Config{ AllowOrigins: []string{"*"}, AllowMethods: []string{"GET", "POST", "OPTIONS"}, AllowHeaders: []string{"Content-Type", "Content-Length", "Accept-Encoding", "X-CSRF-Token", "Authorization", "accept", "origin", "Cache-Control", "X-Requested-With"}, ExposeHeaders: []string{"Content-Length"}, AllowCredentials: true, AllowOriginFunc: func(origin string) bool { return true }, MaxAge: 15 * time.Second, })) api := router.Group("/api") { api.POST("/post", func(c *gin.Context) { var article Article c.BindJSON(&article) ins, err := db.Prepare("INSERT INTO articles(title,content) VALUES(?,?)") if err != nil { log.Fatal(err) } ins.Exec(article.TITLE, article.CONTENT) c.JSON(http.StatusOK, gin.H{"status": "ok"}) }) } router.Run(":4000") }
Vous devez résoudre le problème CORS, cela n'aide clairement pas à obtenir un bon code de réponse.
Votre serveur doit définir les bons en-têtes CORS pour que le navigateur effectue la requête POST. Pour cela, votre serveur doit également répondre aux requêtes
OPTIONS
envoyées par le navigateur.J'ai déjà ajouté
c.Header ("Access-Control-Allow-Origin", "*")
dans le code côté serveur. Mais toujours la même erreur se produit.Votre serveur ne répond qu'aux requêtes POST, comme vu avec
api.POST
, mais il doit également répondre aux requêtes OPTIONS.J'ai compris. Le problème a été résolu. Merci!!