axios.post 请求得到 404
axios.post request gets 404
客户端 (React/axios.post) 无法 post 到服务器端 api (Golang/gin),状态代码为 404。
我想让这个 post 请求成功。
curl 成功写入数据后 mysql table
curl -X POST -H "Content-Type: application/json" -d '{"title":"bbb", "content":"bbb"}' localhost:4000/api/post
但是,在 axios.post 的情况下,会发生 404 错误。
这是目标源代码。
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>
);
}
}
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")
}
我希望 axios.post 请求成功,但实际上失败了,状态为 404。
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)
如错误所述,请求 'has been blocked by CORS policy',这是“Cross-Origin Resource Sharing”的缩写,是浏览器实施的一项安全措施。解决方案是将您的服务器修改为 return 正确的 'Access-Control-Allow-Origin' header.
我在服务器端添加了一些代码后,问题就解决了。
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"})
})
这是我测试的工作代码:
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")
}
客户端 (React/axios.post) 无法 post 到服务器端 api (Golang/gin),状态代码为 404。 我想让这个 post 请求成功。
curl 成功写入数据后 mysql table
curl -X POST -H "Content-Type: application/json" -d '{"title":"bbb", "content":"bbb"}' localhost:4000/api/post
但是,在 axios.post 的情况下,会发生 404 错误。
这是目标源代码。
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>
);
}
}
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")
}
我希望 axios.post 请求成功,但实际上失败了,状态为 404。
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)
如错误所述,请求 'has been blocked by CORS policy',这是“Cross-Origin Resource Sharing”的缩写,是浏览器实施的一项安全措施。解决方案是将您的服务器修改为 return 正确的 'Access-Control-Allow-Origin' header.
我在服务器端添加了一些代码后,问题就解决了。
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"})
})
这是我测试的工作代码:
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")
}