CORS错误,但无论如何都会获取数据

时间:2017-10-13 20:04:43

标签: cors aws-api-gateway fetch-api

我有一个生成的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.logthis.setState永远不会被调用。

我知道CORS是一个常见的痛点,而且很多问题都涉及CORS。我的问题:为什么响应在“网络”选项卡中没有显示错误,同时在控制台中出现错误?

2 个答案:

答案 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.logthis.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请求。你可以从那里观察标题。