如何修复 Fetch API 中的 CORS 问题

Posted

技术标签:

【中文标题】如何修复 Fetch API 中的 CORS 问题【英文标题】:How do I fix CORS issue in Fetch API 【发布时间】:2018-07-21 13:01:30 【问题描述】:

我正在使用 reactjs 构建一个仅限前端的基本天气应用程序。对于 API 请求,我使用 Fetch API。 在我的应用程序中,我从找到的simple API 获取当前位置 并将位置作为 JSON 对象提供。但是当我通过 Fetch API 请求它时,我收到了这个错误。

Failed to load http://ip-api.com/json: Request header field Access-Control-Allow-Origin is not allowed by Access-Control-Allow-Headers in preflight response.

所以我搜索并找到了多种解决方案来解决这个问题。

    在 Chrome 中启用 CORS 可以解决错误,但是当我在 heroku 上部署应用程序时,如何通过移动设备访问它而不会遇到相同的 CORS 问题。 我找到了一个proxy API,它启用了 CORS 请求。但由于这是一个位置请求,这给了我代理服务器的位置。所以这不是一个解决方案。 我已经完成了这个*** question 并将标头添加到我的http 请求的标头中,但它并没有解决问题。 (仍然会出现同样的错误)。

那么我怎样才能永久解决这个问题呢?我可以用来解决 Fetch API 中 http 请求的 CORS 问题的最佳解决方案是什么?

【问题讨论】:

该服务器配置为不允许您从浏览器 (CORS) 获取它。你可以用 cURL 得到它一整天。如果您无法让他们在其 Web 服务器上添加 CORS 标头,请重新考虑您的想法。 【参考方案1】:

如果您要发布、放置或修补请求,则必须使用 body: JSON.stringify(data) 对数据进行字符串化

fetch(URL, 
        
            method: "POST", 
            body: JSON.stringify(data),
            mode: 'cors',
            headers: 
                'Content-Type': 'application/json',
            
        
    ).then(response => response.json())
    .then(data => 
        ....
    )
    .catch((err) => 
        ....
        )
    );

【讨论】:

如何通过获取请求来做到这一点?【参考方案2】:

该 API 似乎是允许的,以 Access-Control-Allow-Origin:* 响应

我还没有弄清楚是什么导致了您的问题,但我认为这不仅仅是fetch API。

这在 Firefox 和 Chrome 中对我来说都很好......

fetch('http://ip-api.com/json')
   .then( response => response.json() )
   .then( data => console.log(data) )

【讨论】:

我在 Fetch API 请求中添加了标头 Access-Control-Allow-Origin:*。但这并不能解决问题。它仅在我使用插件在浏览器中启用 CORS 时才有效。 我似乎遗漏了一些东西,但 you 不应该将Access-Control-Allow-Origin:* 添加到您的请求中——API 服务器将其放入响应中。根据我的测试,他们会这样做。 在阅读了有关添加标头和许多内容之后,我在请求中添加了标头。我用你提到的内容替换了整个 fetch API 请求,它很有魅力。非常感谢 这个参数对我有用:fetch('http://ip-api.com/json', method: "GET", mode: 'cors', headers: 'Content-Type': 'application/json',).then(response => response.json()) 感谢 Nafiu Lawal【参考方案3】:

您应该使用代理解决方案,但传递客户端的 IP 而不是代理。这是您指定的 API 的示例 URL 格式,使用 WikiMedia 的 IP:

http://ip-api.com/json/208.80.152.201

【讨论】:

这行得通。但是当我从不同的 IP 登录时,硬编码 IP 会成为问题吗?那么如何获取客户端 IP,因为 IP 在响应对象中。那么我怎样才能在发送请求之前获取 IP(如您所提到的那样附加在请求中)? 要制作代理,您需要服务器端代码(如 php、ruby 等)。您只需查看传入请求的 IP,在 URL 中使用它,获取响应(仍然在 PHP 中),获取该响应,然后将其发送到实际浏览器(因此浏览器不是发出请求的那个) .这将绕过 CORS 限制,因为该文件位于您自己的域中,并且 CORS 不再适用。 除非您使用 JSONP,否则您将无法单独在 JS 中执行此操作,看来他们支持它:ip-api.com/docs/api:json 谢谢。我会调查的。顺便说一句,这似乎是我请求中的标题问题。通过替换另一个人提到的简单代码来修复它,它就像魅力一样工作

以上是关于如何修复 Fetch API 中的 CORS 问题的主要内容,如果未能解决你的问题,请参考以下文章

如何修复 react app 和 coinbase connect api 上的 cors 错误

使用 fetch、cors 时如何从 json API 获取属性?

如何修复 localhost 中的 react cors 错误?

CORS 阻止访问资源:如何在 Firebase 云功能中修复?

Fetch API 无法加载,cors

Fetch API 无法加载 URL 方案对于 CORS 请求必须是“http”或“https”