CORS 问题 - React/Axios 前端和 Golang 后端
CORS issue - React/Axios Frontend and Golang Backend
我有一个用 Golang 编写的后端 REST API 服务。我在 React 前端使用 axios 来 POST 到 API。即使我认为我已经为前端和后端启用了 CORS,浏览器仍然会抛出这个错误:
Access to XMLHttpRequest at 'http://localhost:8080/winERC20' from origin 'http://localhost:3000' has been blocked by CORS policy: Request header field access-control-allow-origin is not allowed by Access-Control-Allow-Headers in preflight response.
任何人都可以建议我应该如何解决这个问题?
main.go
func main() {
fmt.Println("Server is serving at http://localhost:8080/")
// Init the mux router
router := mux.NewRouter()
router.HandleFunc("/", helloHandler)
router.HandleFunc("/matchingABI", api.MatchingContractABI)
router.HandleFunc("/winERC20", api.WinERC20_controller).Methods("POST", "OPTIONS")
log.Fatal(http.ListenAndServe(":8080", router))
}
api.go
func WinERC20_controller(w http.ResponseWriter, r *http.Request) {
enableCors(&w)
if r.Method == "OPTIONS" {
w.WriteHeader(http.StatusOK)
return
}
// Try to decode the request body into the struct. If there is an error,
// respond to the client with the error message and a 400 status code.
var p winERC20_RequestBody
err := json.NewDecoder(r.Body).Decode(&p)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
...
w.Header().Set("Content-Type", "application/json")
resp := make(map[string]string)
resp["message"] = "Success"
jsonResp, err := json.Marshal(resp)
if err != nil {
log.Fatalf("Error happened in JSON marshal. Err: %s", err)
}
w.Write(jsonResp)
}
func enableCors(w *http.ResponseWriter) {
header := (*w).Header()
header.Add("Access-Control-Allow-Origin", "*")
header.Add("Access-Control-Allow-Methods", "DELETE, POST, GET, OPTIONS")
header.Add("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With")
}
frontend.js
grantERC20(){
// Transfer ERC20 to the player
let url = 'http://localhost:8080/winERC20'
let config = {
headers: {
"Content-Type": "application/json",
'Access-Control-Allow-Origin': '*',
}
}
let data = {
"PublicAddress" : this.props.account,
"Amount": this.props.score
}
axios.post(url, data, config)
.then(
(response) => {console.log(response)},
(error) => {console.log(error);}
);
}
componentDidMount () {
this.grantERC20()
}
为什么要在您的 client-side 代码中向您的请求添加名为 Access-Control-Allow-Origin
的 header? That header is a response header, not a request header。此外,CORS 预检必然会失败,因为您的 CORS 配置不允许这样的请求 header:
header.Add("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With")
补救措施很简单:只需从您的请求中删除 Access-Control-Allow-Origin
header。
此外,您应该考虑依赖一些经过验证的 CORS 中间件,例如 https://github.com/rs/cors.
,而不是“手动”实施 CORS(即 error-prone)
我有一个用 Golang 编写的后端 REST API 服务。我在 React 前端使用 axios 来 POST 到 API。即使我认为我已经为前端和后端启用了 CORS,浏览器仍然会抛出这个错误:
Access to XMLHttpRequest at 'http://localhost:8080/winERC20' from origin 'http://localhost:3000' has been blocked by CORS policy: Request header field access-control-allow-origin is not allowed by Access-Control-Allow-Headers in preflight response.
任何人都可以建议我应该如何解决这个问题?
main.go
func main() {
fmt.Println("Server is serving at http://localhost:8080/")
// Init the mux router
router := mux.NewRouter()
router.HandleFunc("/", helloHandler)
router.HandleFunc("/matchingABI", api.MatchingContractABI)
router.HandleFunc("/winERC20", api.WinERC20_controller).Methods("POST", "OPTIONS")
log.Fatal(http.ListenAndServe(":8080", router))
}
api.go
func WinERC20_controller(w http.ResponseWriter, r *http.Request) {
enableCors(&w)
if r.Method == "OPTIONS" {
w.WriteHeader(http.StatusOK)
return
}
// Try to decode the request body into the struct. If there is an error,
// respond to the client with the error message and a 400 status code.
var p winERC20_RequestBody
err := json.NewDecoder(r.Body).Decode(&p)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
...
w.Header().Set("Content-Type", "application/json")
resp := make(map[string]string)
resp["message"] = "Success"
jsonResp, err := json.Marshal(resp)
if err != nil {
log.Fatalf("Error happened in JSON marshal. Err: %s", err)
}
w.Write(jsonResp)
}
func enableCors(w *http.ResponseWriter) {
header := (*w).Header()
header.Add("Access-Control-Allow-Origin", "*")
header.Add("Access-Control-Allow-Methods", "DELETE, POST, GET, OPTIONS")
header.Add("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With")
}
frontend.js
grantERC20(){
// Transfer ERC20 to the player
let url = 'http://localhost:8080/winERC20'
let config = {
headers: {
"Content-Type": "application/json",
'Access-Control-Allow-Origin': '*',
}
}
let data = {
"PublicAddress" : this.props.account,
"Amount": this.props.score
}
axios.post(url, data, config)
.then(
(response) => {console.log(response)},
(error) => {console.log(error);}
);
}
componentDidMount () {
this.grantERC20()
}
为什么要在您的 client-side 代码中向您的请求添加名为 Access-Control-Allow-Origin
的 header? That header is a response header, not a request header。此外,CORS 预检必然会失败,因为您的 CORS 配置不允许这样的请求 header:
header.Add("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With")
补救措施很简单:只需从您的请求中删除 Access-Control-Allow-Origin
header。
此外,您应该考虑依赖一些经过验证的 CORS 中间件,例如 https://github.com/rs/cors.
,而不是“手动”实施 CORS(即 error-prone)