首页 > 解决方案 > REST API 调用从 curl 或 python 成功,但在浏览器中失败

问题描述

我正在尝试建立一个网站,该网站通过 REST API 从公司拥有的 JIRA Board 请求 JIRA 数据,并在不同的图表中显示请求的数据。在使用 JavaScript 开发时,我遇到了CORS 标头“Access-Control-Allow-Origin”缺失错误,因此无法访问数据。这是一些代码:

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 脚本在我的浏览器控制台中抛出了上述错误,而具有相同参数的简单 python 脚本或 curl 命令可以工作并输出数据。这怎么可能?

标签: javascriptapirestcurljira

解决方案


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

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

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

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

CORS + HTTP OPTIONS 是保护 API 访问和减轻跨站点脚本引起的过多安全和隐私问题的武器库中的一种机制。

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

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


推荐阅读