我有一个生成的React站点,我在S3存储桶中托管。我的一个组件尝试在加载时获取内容:
require('isomorphic-fetch')
...
componentDidMount() {
fetch(`${url}`)
.then(res => {
console.log(res);
this.setState({
users: res
})
})
.catch(e => {
// do nothing
})
}
我提取的url
是AWS API网关。我通过下拉列表在那里启用了CORS,没有更改默认配置。
在我的控制台中,对于远程站点和开发期间的本地,我看到:
"无法加载url
:否' Access-Control-Allow-Origin'标头出现在请求的资源上。"等
但是,在Chrome网络标签中,我可以看到请求和响应,状态为200等。但是,在控制台中,我的console.log
和this.setState
永远不会被调用。
我知道CORS是一个常见的痛点,而且很多问题都涉及CORS。我的问题:为什么响应在“网络”选项卡中没有显示错误,同时在控制台中出现错误?
答案 0 :(得分:3)
fetch(`${url}`)
调用返回使用Response
object解析的承诺,而Response
对象提供的methods解析为text,{{3} },或JSON data。
因此,要获得所需的数据,您需要执行以下操作:
componentDidMount() {
fetch(`${url}`)
.then(res => res.text())
.then(text => {
console.log(text);
this.setState({
users: text
})
.catch(e => {
// do nothing
})
}
无法加载网址:请求的资源上没有“Access-Control-Allow-Origin”标头。“etc
这意味着浏览器不允许您的前端代码访问服务器的响应,因为响应不包含Access-Control-Allow-Origin
响应标头。
因此,为了使上述代码有效,您需要修复该服务器上的服务器配置,以便它发送必要的Access-Control-Allow-Origin
响应标头。
但是,在Chrome网络标签中,我可以看到请求和响应,状态为200等。但是,在控制台中,我的
console.log
和this.setState
永远不会被调用。
在服务器未发送Access-Control-Allow-Origin
响应标头的情况下,这是预期的。在这种情况下,浏览器仍然会收到响应 - 这就是为什么你可以在devtools网络选项卡中看到它 - 但仅仅因为浏览器获得响应并不意味着它会将响应公开给你的前端JavaScript代码。
如果代码包含Access-Control-Allow-Origin
响应标头,浏览器将只允许您的代码访问该响应;如果响应不包含该标题,则浏览器会阻止您的代码访问它。
我的问题:为什么响应在“网络”选项卡中没有显示错误,同时在控制台中出现错误?
出于上述原因。浏览器本身在获取响应时没有错误。但是您的代码遇到错误,因为它试图访问不存在的响应 - 因为浏览器没有公开对您的代码的响应。
答案 1 :(得分:0)
您可能会看到OPTIONS
而不是GET的状态200。 CORS有一个处理遗留的设置,因此不会让您的客户感到困惑。我最后一次在React应用程序中这样做了。您的错误是您的CORS配置不正确(显然很抱歉)。如果Chrome没有正确获取标题,则Chrome不会让您的客户端进入后端。其他浏览器也可能,也可能是React。如果只有一方启用了CORS,它可能是某种HTTP协议。有人可以在那里纠正我。这与从HTTPS向HTTP发送请求的安全性相似。 Chrome阻止了它。
在我看来,这是你的后端。 CORS未激活或者会打开该标头,之后,您会在前端客户端看到有关原点不匹配的错误。
根据我的经验,这是一个2-3步组合,请确保OPTIONS
不向您的客户发送混乱信号(查找与200
相关的设置)。这是后端的配置设置。然后,确保后端配置为使用CORS。您特别需要输入后端预期来自的流量的源主机名和端口。
如果我看到除了React之外你使用的语言和/或框架,我可能会提供更好的输入。
这是你在Express JS和后端节点中所做的:
const cors = require('cors')
// note http or https
app.use(cors({
origin: 'http://example.com:1337',
//origin: '*',
methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',
optionsSuccessStatus: 200
// some legacy browsers (IE11, various SmartTVs) choke on 204
}))
我的上一个React应用程序在没有optionsSuccessStatus的情况下通过在失败时抛出成功来引爆。
为了给你一些图像,CORS很简单但很挑剔。这是一个简单的对齐问题。一旦你的后端配置为a)使用CORS和b)知道接受流量的人,就完成了。一旦您的前端配置为处理此流量,它就完成了。这就像在圆孔中对齐方形挂钩,直到您将配置设置对齐。
尝试使用Postman
向后端发送一些GET请求。你可以从那里观察标题。