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
OPTIONSenvoyé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!!