REST API 调用从 curl 或 python 成功,但在浏览器中失败

REST API call succeeds from curl or python, but fails in browser

我正在尝试构建一个网站,该网站通过 REST API 从 company-owned JIRA Board 请求 JIRA 数据,并在不同的图表中显示请求的数据。在使用 JavaScript 开发时,我 运行 进入 CORS header 'Access-Control-Allow-Origin' missing 错误,因此无法访问数据。 这是一些代码:

var url = myUrl;

var auth_string = myJira_user + ":" + myJira_password;
var encoded_string = btoa(auth_string);

var http_headers = {
  "Content-Type": "application/json",
  Authorization: "Basic " + encoded_string
};
var headers = new Headers(http_headers);

fetch(url, headers)
  .then(response => {
    return response.json();
  })
  .then(data => {
    console.log(data);
  })
  .catch(err => {});

此 JS 脚本在我的浏览器控制台中抛出 above-mentioned 错误,而具有相同参数的简单 python 脚本或 curl 命令可以工作并输出数据。这怎么可能?

现代浏览器首先通过 HTTP OPTIONS 调用检查 API 服务器上的 CORS 策略。这称为“预检请求”。

CORS: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS

HTTP OPTIONS: https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/OPTIONS

实际上,浏览器首先检查 API 服务器是否有权从来源调用和使用 APIs(用户浏览的网站,由域标识,协议和端口)。如果 API 服务器期望从源进行调用,它 return 是对 OPTIONS 调用的成功响应,然后浏览器继续进行 GET/POST/etc 调用。但是,如果 API 服务器无法识别 OPTIONS 调用的来源,它将 return 失败响应,并且浏览器不会继续进行 API 调用,而是生成异常你已经观察到了。

CORS + HTTP OPTIONS 是保护 API 访问和缓解跨站点脚本引起的大量安全和隐私问题的一种机制。

但就您而言,CORS 不会影响从非浏览器应用程序发出的调用。非浏览器应用程序,例如 CURL 或您可以在 Python、Node 等中编写的任何代码,不会进行 OPTIONS 调用,因此 API 服务器的 CORS 策略不适用。

您可以设置一个 middleman/proxy 服务器来接收来自您的 Web 应用程序的 API 请求,调用目标 API 服务器,并编组返回响应,从而规避 CORS 策略。