即使在客户端设置 Access-Control-Allow-Origin 或其他 Access-Control-Allow-* headers 后也会出现 CORS 错误

CORS error even after setting Access-Control-Allow-Origin or other Access-Control-Allow-* headers on client side

我有一个使用 webpack-simple 选项生成的 Vue 应用程序。我正在尝试向 https://api.forismatic.com/api/1.0/?method=getQuote&format=json&lang=en 发出 GET 请求,但出现错误:

XMLHttpRequest cannot load https://api.forismatic.com/api/1.0/?method=getQuote&format=json&lang=en. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8080' is therefore not allowed access.

我正在使用 vue-resource 并添加了:

Vue.http.headers.common['Access-Control-Allow-Origin'] = '*'

没有效果。

我还在 webpack.config.jsdevServer 选项中添加了这个:

devServer: {
  historyApiFallback: true,
  noInfo: true,
  headers: {
    "Access-Control-Allow-Origin": "*"
  }
}

这也没有解决问题;错误消息保持不变。

如何解决这个问题?

Access-Control-Allow-Origin 是一个 响应 header 请求到达的服务器必须发送。

和所有其他 Access-Control-Allow-* header 是服务器发送的响应 header。

如果您不控制您的请求发送到的服务器,响应的问题只是缺少 Access-Control-Allow-Origin header 或其他 Access-Control-Allow-* headers 您仍然可以让事情正常进行——通过 CORS 代理发出请求。

您可以使用 https://github.com/Rob--W/cors-anywhere/.
中的代码轻松地 运行 您自己的代理 您还可以在 2-3 分钟内轻松地将自己的代理部署到 Heroku,使用 5 个命令:

git clone https://github.com/Rob--W/cors-anywhere.git
cd cors-anywhere/
npm install
heroku create
git push heroku master

在 运行 执行这些命令后,您最终会得到自己的 CORS Anywhere 服务器 运行,例如 https://cryptic-headland-94862.herokuapp.com/

现在,在您的请求 URL 前加上代理的 URL:

https://cryptic-headland-94862.herokuapp.com/https://example.com

添加代理 URL 作为前缀会导致通过您的代理发出请求,这:

  1. 将请求转发给 https://example.com
  2. 收到来自 https://example.com 的响应。
  3. Access-Control-Allow-Origin header 添加到响应中。
  4. 将添加了 header 的响应传递回请求前端代码。

然后浏览器允许前端代码访问响应,因为带有 Access-Control-Allow-Origin 响应 header 的响应是浏览器看到的。

即使请求是触发浏览器执行 CORS 预检 OPTIONS 请求的请求,这也有效,因为在这种情况下,代理还会发回 Access-Control-Allow-HeadersAccess-Control-Allow-Methods headers 需要 s 才能使预检成功。

并且如果您有前端代码将 Access-Control-Allow-Origin header 或其他 Access-Control-Allow-* header 添加到请求中,请删除该代码——因为唯一影响您的是通过添加这些请求 headers 是,您触发浏览器发送 a CORS preflight OPTIONS request 而不是代码中的实际 GETPOST 请求。

对于无法访问 API 设置的用户,请免费使用代理 service from Rob--W

function doCORSRequest(appUrl) {
  const cors_api_url = 'https://cors-anywhere.herokuapp.com/';
  let nUrl = cors_api_url + appUrl;

  fetch(nUrl)
    .then(response => {
      if(response.status !== 200) {
        alert("Error :( try later.")
        return;
      }
      response.json()
        .then(data => showResult(data))
    })
}

doCORSRequest(yourURL);