使用基本身份验证的 GET 请求来自 Postman 但不是来自浏览器

2022-01-20 00:00:00 request fetch get javascript odata

我正在使用 odata api,当我使用邮递员发出 GET 请求时,效果很好,我得到了预期的响应.

但是,当我从我的 React 应用程序中使用 fetch 请求时,该请求会引发 401,使用的标头与我之前在 Postman 中使用的标头相同.并且它说 对预检请求的响应没有通过访问控制检查:请求的资源上不存在Access-Control-Allow-Origin"标头.因此,不允许访问 Origin 'http://localhost:3000'.响应的 HTTP 状态代码为 401.

知道如何解决这个请求吗?谢谢!

fetch('https://api4.successfactors.com/odata/v2/', {方法:'GET',标题:{authentication: `Basic ${auth}`,//auth 是经过编码的base64 username:password},}).then(response => response.json()).then((响应) => {console.log('in response: ', response);}).catch((错误) => {console.log('在 fetchJobs 错误:', 错误);});

这是我得到的 401....

解决方案

这很可能是因为 Postman 可能没有在您的 GET 之前发送预检 Options 请求,并且收到 GET 响应后,不会执行任何类型的 cors 检查(因为无论如何它都没有真正意义).

另一方面,当从您的网页运行代码时,Chrome 会执行预检 Options 以确定允许将哪些跨域请求参数发送到远程服务器并检查是否对 Options req 的响应具有适当的 Access-Control-Allow-Origin 标头以授权您的 origin (即您的页面的域'正在发出请求).

通常,预检 Options 由浏览器发送到服务器,以询问服务器是否允许执行它即将执行的操作 - 在您的情况下,是 GET.如果远程(跨域)服务器没有响应 prelight Options 请求并在响应中授权您的 GET 的正确标头,则浏览器将不会发送.但是,您甚至还没有走那么远,因为对您的 Options 请求的响应本身甚至没有通过 cors origin 检查.

如果您控制服务器,则需要通过在响应上设置 Access-Control-Allow-Origin 标头以包含 来响应 Options 请求>origin 您的请求页面,并设置 Access-Control-Allow-Methods 以包含 GET (可能还有 OPTIONS).如果您不控制远程服务器,则很可能任何普通的 api 服务(例如您尝试访问的那个)在其后端都有一些配置,您可以在某处设置以授权您的 origin.p>

您可以在 这里 阅读更多关于 cors 行为的信息/p>

I'm working with an odata api, and when I'm using postman to do a GET request, works perfect and I get the response as I was expecting.

But when I use a fetch request from my React app, the request throws a 401, using the same headers as I previously used in Postman. and it says that Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. The response had HTTP status code 401.

Any idea about how to solve this request? Thanks!

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);
  });

This is the 401 that I'm getting....

解决方案

This is most likely because Postman is probably not sending a preflight Options request before your GET, and upon receipt of the GET response doesn't perform any kind of cors check (since it wouldn't really make sense to anyway).

On the other hand, when running code from your webpage Chrome is both performing a preflight Options in order to ascertain what cross-domain request parameters it's allowed to send to the remote server and checking if the response to the Options req has the appropriate Access-Control-Allow-Origin header on to authorise your origin (i.e. the domain of the page you're making the request from).

Typically, a preflight Options is sent to the server by a browser to ask the server if it's allowed to perform the operation it's about to perform - in your case, a GET. If the remote (cross-domain) server doesn't respond to the prelight Options request with the correct headers in the response authorising your GET then the browser won't send one. You're not even getting that far however, since the response to your Options request doesn't even itself pass a cors origin check.

If you control the server, you need to respond to the Options request by setting the Access-Control-Allow-Origin header on the response to include the origin of your request page, and also to set the Access-Control-Allow-Methods to include GET (and probably OPTIONS). If you don't control the remote server, it's likely any normal api service such as the one you're trying to hit has some configuration in their backend you can set somewhere to authorise your origin.

You can read up more on cors behaviour here

相关文章