代码之家  ›  专栏  ›  技术社区  ›  Mitch Lillie

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

  •  6
  • Mitch Lillie  · 技术社区  · 7 年前

    我有一个生成的React网站,我托管在一个S3存储桶中。我的一个组件在加载时尝试获取某些内容:

    require('isomorphic-fetch')
    ...
    
    componentDidMount() {
      fetch(`${url}`)
        .then(res => {
          console.log(res);
          this.setState({
            users: res
          })
        })
        .catch(e => {
          // do nothing
        })
    }
    

    这个 url

    在我的控制台中,对于远程站点和开发过程中的本地站点,我看到:

    “未能加载 url

    然而,在Chrome网络选项卡中,我可以看到请求和响应,状态为200等。在控制台中,我的 console.log this.setState

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

    2 回复  |  直到 5 年前
        1
  •  10
  •   sideshowbarker Miguel Tomás    3 年前

    这个 fetch(`${url}`) Response object ,并且 对象提供 methods 解决方案 text , JSON data Blob .

    因此,要获得所需的数据,需要执行以下操作:

    componentDidMount() {
      fetch(`${url}`)
        .then(res => res.text())
        .then(text => {
          console.log(text);
          this.setState({
            users: text
        })
        .catch(e => {
          // do nothing
        })
    }
    

    加载url失败:请求的资源上不存在“Access Control Allow Origin”标头。“等等

    Access-Control-Allow-Origin 标题。

    因此,为了使上述代码正常工作,您需要修复该服务器上的服务器配置,以便它发送必要的 访问控制允许原点

    然而,在Chrome网络选项卡中,我可以看到请求和响应,状态为200等。在控制台中,我的 console.log this.setState 但是,从未调用。

    如果服务器不发送 访问控制允许原点 响应标题。在这种情况下,浏览器仍然会获得响应,这就是为什么您可以在devtools网络选项卡中看到它,但仅仅因为浏览器获得了响应并不意味着它会将响应公开给前端JavaScript代码。

    浏览器仅允许您的代码访问包含 访问控制允许原点 响应标头;如果响应不包括该标题,则浏览器会阻止您的代码访问它。

    我的问题是:为什么响应在网络选项卡中没有显示错误,而同时在控制台中显示错误?

    出于上述原因。浏览器本身在获取响应时不会出错。但是你的代码出错了,因为它试图访问 res 物件 对象,因为浏览器没有向您的代码公开响应。

        2
  •  0
  •   agm1984    7 年前

    您可能会看到 OPTIONS 不是GET。CORS有一个处理遗留问题的设置,所以它不会混淆您的客户。上次我不得不在React应用程序中这样做。您的错误是您的CORS配置不正确(很抱歉,显然)。如果Chrome不能正确获取标题,它不会让你的客户端tlak到后端。其他浏览器可能也会做出反应。如果只有一侧启用了CORS,则它可能是某种HTTP协议。有人可以纠正我。这与从HTTPS向HTTP发送请求的安全性考虑类似。铬合金将其阻挡。

    在我看来,这就像是你的后端。CORS不活动,或者它会打开该标头,然后,您会在前端客户端中看到关于原点不匹配的错误。

    选项 不要向你的客户发送令人困惑的信号(寻找与之相关的设置 200 ). 这是后端的配置设置。然后,确保后端配置为使用CORS。您特别需要输入后端预期流量的源主机名和端口。

    如果我知道你在使用什么语言和/或框架,我可能会提供更好的输入。

    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的情况下引爆,当它失败时抛出success。

    为了给你一点图像处理,CORS很简单,但很挑剔。这是一个简单的对齐问题。一旦您的后端配置为a)使用CORS和b)知道接受来自谁的流量,就完成了。一旦您的前端配置为处理此流量,它就完成了。这就像在一个圆孔中对齐一个正方形的钉子,直到对齐配置设置。

    尝试使用 Postman 向后端发送一些GET请求。您可以从那里观察标题。