英文:
Preflight Doesn't Pass Control Check Access-Control-Allow-Origin Not Present
问题
我有一个在React中运行的简单客户端。我正在尝试使用Axios进行GET请求,请求的目标是我本地运行的Go服务器。React代码运行在端口3000上,Go服务器运行在端口4000上。
如果我将GET请求本身粘贴到浏览器窗口中,它可以正常工作:http://localhost:4000/numberconverter?number=10&oldBase=10&newBase=2
我已经进行了一些研究,并找到了这篇帖子,但插件和Chrome选项并没有帮助。这不是我所做的唯一研究,但似乎是最有希望的。大部分我找到的内容都不涉及Go服务器。
我还找到了这篇帖子,但它也没有解决我的问题。如果我取消服务器中的代码注释,它仍然无法正常工作。
如果我将允许的方法更改为:
writer.Header().Set("Access-Control-Allow-Methods", "GET, POST, PATCH, PUT, DELETE, OPTIONS")
它会返回一个405错误。服务器会打印出以下内容:
&{0xc4200f4000 0xc42000a500 {} 0x10ec430 true false false false 0xc4200143c0 {0xc420100000 map[Access-Control-Allow-Origin:[*] Access-Control-Allow-Methods:[GET, POST, PATCH, PUT, DELETE, OPTIONS] Content-Type:[text/plain; charset=utf-8] X-Content-Type-Options:[nosniff]] false false} map[Access-Control-Allow-Origin:[*] Access-Control-Allow-Methods:[GET, POST, PATCH, PUT, DELETE, OPTIONS] Content-Type:[text/plain; charset=utf-8] X-Content-Type-Options:[nosniff]] true 19 -1 405 false false [] 0 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] 0xc4200620e0}
我想知道这个问题是在服务器端还是客户端端,以及如何解决这个问题?
客户端代码:
import React, {Component} from 'react';
import axios from 'axios';
class Converter extends Component {
constructor(props) {
super(props);
this.state = {
// number: 0,
// base: 10,
// newBase: 10
};
this.convertButtonPressed = this.convertButtonPressed.bind(this);
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
const target = event.target;
const value = target.value;
const name = target.name;
this.setState({
[name]: value
});
}
convertButtonPressed(event) {
axios({
method: 'GET',
baseURL: 'http://localhost:4000/',
url: '/numberconverter',
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, PATCH, PUT, DELETE, OPTIONS',
'Access-Control-Allow-Headers': 'Origin, Content-Type, X-Auth-Token'
},
params: {
number: this.state.number,
oldBase: this.state.base,
newBase: this.state.newBase
}
});
}
render() {
return (
<div className="App">
<p>Number Converter</p>
<div>
Number:
<input name="number" onChange={this.handleChange} type="text" placeholder="Number"></input><br />
Base:
<input name="base" onChange={this.handleChange} type="text" placeholder="Base"></input><br />
New Base:
<input name="newBase" onChange={this.handleChange} type="text" placeholder="New Base"></input><br />
</div>
<button onClick={this.convertButtonPressed}>Convert</button>
</div>
);
}
}
export default Converter;
服务器代码:
package rest
// Example:
// http://localhost:3000/numberconverter?number=500000&oldBase=10&newBase=16
import (
"fmt"
"log"
"net/http"
"../converter"
)
// Start starts the server
func Start() {
//muxRouter := http.NewServeMux()
//muxRouter.HandleFunc("/numberconverter", numberconverter)
//http.Handle("/", muxRouter)
http.HandleFunc("/numberconverter", numberconverter)
log.Fatal(http.ListenAndServe(":4000", nil))
}
func numberconverter(writer http.ResponseWriter, response *http.Request) {
//writer.Header().Set("Access-Control-Allow-Origin", "*")
//writer.Header().Set("Access-Control-Allow-Methods", "*")
//writer.Header().Set("Content-Type", "text/html; charset=utf-8")
// Check if the method is a get
if response.Method != http.MethodGet {
http.Error(writer, http.StatusText(405), 405)
fmt.Println(writer)
return
}
number := response.FormValue("number")
oldBase := response.FormValue("oldBase")
newBase := response.FormValue("newBase")
result := converter.ConvertStringNumberToNewBase(number, oldBase, newBase)
fmt.Fprintf(writer, "%s base %s is %s in base %s", number, oldBase, result, newBase)
}
英文:
I have a simple client running in React. I am trying to make a GET request using Axios to a Go server that I have running locally. The React code is running on port 3000, the Go server on 4000.
If I paste the GET request itself in the browser window it works fine: http://localhost:4000/numberconverter?number=10&oldBase=10&newBase=2
I've done some research and found this post, but the plugin and the Chrome options do not help. That isn't the only research I've done, but that seemed to be the most promising. Most of the stuff I've found doesn't involve a Go server.
I've also found this post, but that also did not solve my problem. If I uncomment the code in the server it still fails.
If I change the allowed methods to:
writer.Header().Set("Access-Control-Allow-Methods", "GET, POST, PATCH, PUT, DELETE, OPTIONS")
It fails with a 405 error. The server prints out this:
&{0xc4200f4000 0xc42000a500 {} 0x10ec430 true false false false 0xc4200143c0 {0xc420100000 map[Access-Control-Allow-Origin:[*] Access-Control-Allow-Methods:[GET, POST, PATCH, PUT, DELETE, OPTIONS] Content-Type:[text/plain; charset=utf-8] X-Content-Type-Options:[nosniff]] false false} map[Access-Control-Allow-Origin:[*] Access-Control-Allow-Methods:[GET, POST, PATCH, PUT, DELETE, OPTIONS] Content-Type:[text/plain; charset=utf-8] X-Content-Type-Options:[nosniff]] true 19 -1 405 false false [] 0 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] 0xc4200620e0 0}
I guess my question is whether this is a problem on the server side or the client side as well as how could I fix the problem?
Client:
import React, {Component} from 'react';
import axios from 'axios';
class Converter extends Component {
constructor(props) {
super(props);
this.state = {
// number: 0,
// base: 10,
// newBase: 10
};
this.convertButtonPressed = this.convertButtonPressed.bind(this);
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
const target = event.target;
const value = target.value;
const name = target.name;
this.setState({
[name]: value
});
}
convertButtonPressed(event) {
axios({
method: 'GET',
baseURL: 'http://localhost:4000/',
url: '/numberconverter',
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, PATCH, PUT, DELETE, OPTIONS',
'Access-Control-Allow-Headers': 'Origin, Content-Type, X-Auth-Token'
},
params: {
number: this.state.number,
oldBase: this.state.base,
newBase: this.state.newBase
}
});
}
render() {
return (
<div className="App">
<p>Number Converter</p>
<div>
Number:
<input name="number" onChange={this.handleChange} type="text" placeholder="Number"></input><br />
Base:
<input name="base" onChange={this.handleChange} type="text" placeholder="Base"></input><br />
New Base:
<input name="newBase" onChange={this.handleChange} type="text" placeholder="New Base"></input><br />
</div>
<button onClick={this.convertButtonPressed}>Convert</button>
</div>
);
}
}
export default Converter;
Server:
package rest
// Example:
// http://localhost:3000/numberconverter?number=500000&oldBase=10&newBase=16
import (
"fmt"
"log"
"net/http"
"../converter"
)
// Start starts the server
func Start() {
//muxRouter := http.NewServeMux()
//muxRouter.HandleFunc("/numberconverter", numberconverter)
//http.Handle("/", muxRouter)
http.HandleFunc("/numberconverter", numberconverter)
log.Fatal(http.ListenAndServe(":4000", nil))
}
func numberconverter(writer http.ResponseWriter, response *http.Request) {
//writer.Header().Set("Access-Control-Allow-Origin", "*")
//writer.Header().Set("Access-Control-Allow-Methods", "*")
//writer.Header().Set("Content-Type", "text/html; charset=utf-8")
// Check if the method is a get
if response.Method != http.MethodGet {
http.Error(writer, http.StatusText(405), 405)
fmt.Println(writer)
return
}
number := response.FormValue("number")
oldBase := response.FormValue("oldBase")
newBase := response.FormValue("newBase")
result := converter.ConvertStringNumberToNewBase(number, oldBase, newBase)
fmt.Fprintf(writer, "%s base %s is %s in base %s", number, oldBase, result, newBase)
}
答案1
得分: 0
一旦我在React代码中注释掉了头部信息,GET请求就可以正常工作了。我想感谢sideshowbarker提供的答案,非常感谢。
convertButtonPressed(event) {
axios({
method: 'GET',
baseURL: 'http://localhost:4000/',
url: '/numberconverter',
// headers: {
// 'Access-Control-Allow-Origin': '*',
// 'Access-Control-Allow-Methods': 'GET, POST, PATCH, PUT, DELETE, OPTIONS',
// 'Access-Control-Allow-Headers': 'Origin, Content-Type, X-Auth-Token'
// },
params: {
number: this.state.number,
oldBase: this.state.base,
newBase: this.state.newBase
}
});
}
英文:
Once I commented out the headers in the React code the GET request worked. I'd like to thank sideshowbarker for the answer. I really appreciate it.
convertButtonPressed(event) {
axios({
method: 'GET',
baseURL: 'http://localhost:4000/',
url: '/numberconverter',
// headers: {
// 'Access-Control-Allow-Origin': '*',
// 'Access-Control-Allow-Methods': 'GET, POST, PATCH, PUT, DELETE, OPTIONS',
// 'Access-Control-Allow-Headers': 'Origin, Content-Type, X-Auth-Token'
// },
params: {
number: this.state.number,
oldBase: this.state.base,
newBase: this.state.newBase
}
});
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论