我试图在我的浏览器中禁用CORS的情况下进行API调用。该应用程序是使用react-create-app创建的。它使用webpack和webpackDevServer for dev。我在这里找到的所有答案都说将以下代码放入我的webpack.config文件
devServer: {
headers: {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS",
"Access-Control-Allow-Headers": "X-Requested-With, content-type, Authorization"
}
}
但是,我已经在很多不同的地方尝试过它并且它不起作用。
我继续得到错误
Failed to load resource: the server responded with a status of 500 ()
和
Failed to load ... Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. The response had HTTP status code 500.
我还尝试将我的呼叫从axios呼叫更改为提取呼叫
return fetch(process.env.REACT_APP_API_URL + "/prod/user", {
mode: 'no-cors',
credentials: 'include',
method: "GET",
headers: {
"x-api-key": process.env.REACT_APP_API_KEY
}
})
.then(response => {
return response.json()
})
.then(resp => dispatch(receiveUsers(resp.data)))
.catch(error => {console.log(error)})
这让我更接近但控制台现在正在返回
Response {type: "opaque", url: "", redirected: false, status: 0, ok: false, …}
如何解决此CORS问题?在此先感谢您的帮助!
答案 0 :(得分:2)
无法添加评论,所以我会把它作为答案。
如果您尝试访问由其他节点应用或其他主机提供的API。您可以配置webpack-dev-server以将该请求代理到真实服务器。
查看Create React App Doc: Proxying API Requests in Development了解详情。
答案 1 :(得分:0)
您看到对预检OPTIONS请求的500响应这一事实让我觉得,Web服务器根本不允许OPTIONS请求方法。
许多网络服务器默认只允许使用HEAD,GET和POST,因此这是我要检查的第一件事。
如果这没有帮助,请确保上述webpack.config
代码针对所有请求(即OPTIONS和GET / POST)运行。
如果这没有帮助,请向OPTIONS和GET请求发布一整套请求和响应标头,让我们看看我们从哪里开始。
答案 2 :(得分:0)
最好的选择是使用代理,尤其是在使用外部API或多个API的情况下。
只需安装proxy-middleware
并创建文件src/setupProxy.js
,然后在文件内部,可以向其中添加类似的代码:
const proxy = require('proxy-middleware');
module.exports = app => {
// setup proxies
// 1st api
app.use("/etherscan", "http://api.etherscan.io/api");
// 2nd api
app.use("/cryptocompare", "https://min-api.cryptocompare.com/data");
// also it's better to use .env variables
const {REACT_APP_API_ETHERSCAN_PROXY, REACT_APP_API_ETHERSCAN_BASE_URL} = process.env;
app.use(REACT_APP_API_ETHERSCAN_PROXY, REACT_APP_API_ETHERSCAN_BASE_URL);
};
对于您的API,如果可以从.env变量中获取基本URL,则也更好,例如:
const {REACT_APP_API_ETHERSCAN_PROXY, REACT_APP_API_ETHERSCAN_BASE_URL} = process.env;
const baseURL = REACT_APP_API_ETHERSCAN_PROXY || REACT_APP_API_ETHERSCAN_BASE_URL;
其他建议:您可以看看axios来创建具有默认属性的API实例,例如:
,而不是为每个API调用保持传递process.env.REACT_APP_API_URL和标头的方式const {
REACT_APP_API_ETHERSCAN_PROXY,
REACT_APP_API_ETHERSCAN_BASE_URL,
REACT_APP_API_TIMEOUT,
REACT_APP_API_ETHERSCAN_KEY
} = process.env;
export const etherscanAPI = axios.create({
"baseURL": REACT_APP_API_ETHERSCAN_PROXY || REACT_APP_API_ETHERSCAN_BASE_URL,
"timeout": parseInt(REACT_APP_API_TIMEOUT),
"headers": {
"X-Requested-With": "XMLHttpRequest"
},
"params": {
"apiKey": REACT_APP_API_ETHERSCAN_KEY
}
});
然后etherscanAPI.get("/whatever")