Postman可以正常使用基本身份验证的GET请求,但浏览器无法正常工作。

9
我正在使用OData API,当我使用Postman进行GET请求时,一切正常,并且我得到了预期的响应。 Postman Request 但是当我从我的React应用程序使用fetch请求时,请求会抛出401错误,使用与我之前在Postman中使用的相同标头。并且它说:响应预检请求未通过访问控制检查:所请求的资源上没有“Access-Control-Allow-Origin”标头。因此,不允许来自“http://localhost:3000”的访问。响应的HTTP状态代码为401。 有任何解决这个问题的想法吗? 谢谢!

fetch('https://api4.successfactors.com/odata/v2/', {
  method: 'GET',
  headers: {
    authorization: `Basic ${auth}`, //auth is the encoded base64 username:password
  },
})
  .then(response => response.json())
  .then((response) => {
    console.log('in response: ', response);
  })
  .catch((error) => {
    console.log('in fetchJobs error: ', error);
  });

这是我得到的401错误.... 在此输入图片描述
3个回答

22
这个问题最可能是因为Postman在你的GET之前没有发送预检Options请求,并且在收到GET响应后没有执行任何cors检查(因为实际上这也没有意义)。
另一方面,当从网页中运行代码时,Chrome会执行预检Options以确定它允许向远程服务器发送哪些跨域请求参数,并检查Access-Control-Allow-Origin头是否在Options请求的响应中授权你的origin(即你发出请求的页面的域名)。
通常,浏览器会向服务器发送预检Options请求,以询问服务器是否允许执行即将执行的操作-在你的情况下,就是一个GET。如果远程(跨域)服务器没有正确地在Options响应中响应预检Options请求并授权你的GET,则浏览器不会发送请求。然而,你甚至无法通过预检Options请求获得响应,因为它本身没有通过cors origin检查。
如果你控制服务器,你需要通过设置响应中的Access-Control-Allow-Origin头来包括请求页面的origin,并将Access-Control-Allow-Methods设置为包括GET(以及可能的OPTIONS)。如果你不控制远程服务器,则很可能任何正常的api服务(例如你要访问的服务)都有一些后端配置,你可以设置其中某个来授权你的origin
你可以在这里了解更多关于cors行为的信息。

嗨@Rhys,如果我没有访问后端...(那就是情况)我该怎么解决这个问题? - JC Garcia
@JCGarcia,如果您从与要访问的服务器相同的域中进行请求,则不会出现此问题。如果您在服务器端进行请求,也不会有这个问题,但是请仔细考虑您所做决策的安全性/安全性影响,因为这是CORS的首要目的之一。 - Rhys
我了解安全方面的考虑,事实上该 API 仅允许读取数据,因此来自客户端的请求将是理想的选择。而且,整个应用程序都是无服务器的,我希望保持这种方式。既然您已经解释了 CORS 问题(感谢顺便提醒,这确实是一个好问题),下一步就是找到第三方服务,有任何推荐吗? - JC Garcia
好的...就我所理解的,客户端没有解决方案。我应该建立一个服务器来解决它...对吗? - JC Garcia
让我们在聊天中继续这个讨论 - JC Garcia
显示剩余2条评论

2
您遇到了CORS问题,为了解决它,您需要在后端启用CORS。

嗨@Mike_Tung,对我来说很不幸...我没有访问后端的权限,所以那是不可能的...有什么办法可以绕过去吗? - JC Garcia
1
无法绕过,因为这是纯后端安全措施,防止您访问资源。您可以在完全相同的服务器上部署,但这很危险。 - Mike Tung
什么是最简单的解决方案?建立一个服务器吗?只为了一个查询似乎有些过度...但如果是这样,你会推荐什么呢? - JC Garcia

0

最理想的方法是允许您的服务器允许来自不同域的调用,但如果您无法访问后端和测试服务,则可以安装此Chrome插件以绕过预检请求。 cors chrome extension


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接