我试图从惠普Alm的REST API中获取一些数据。它使用一个小的curl脚本工作得很好——我得到了我的数据。

现在用JavaScript、fetch和ES6(或多或少)来实现这一点似乎是一个更大的问题。我一直收到这个错误信息:

无法加载获取API。对飞行前请求的响应则不然 pass访问控制检查:没有' access - control - allow - origin '头 显示在所请求的资源上。“http://127.0.0.1:3000”是 因此不允许访问。响应的HTTP状态代码为501。 如果不透明响应满足您的需求,请将请求的模式设置为 'no-cors'获取禁用CORS的资源。

我明白这是因为我试图从我的本地主机内获取数据,解决方案应该使用跨起源资源共享(CORS)。我认为我确实这样做了,但不知为何,它要么忽略了我在头文件中写的内容,要么是其他问题。

那么,是否存在执行问题?我做错了吗?很遗憾,我无法查看服务器日志。我真的有点卡在这里了。

function performSignIn() {

  let headers = new Headers();

  headers.append('Content-Type', 'application/json');
  headers.append('Accept', 'application/json');

  headers.append('Access-Control-Allow-Origin', 'http://localhost:3000');
  headers.append('Access-Control-Allow-Credentials', 'true');

  headers.append('GET', 'POST', 'OPTIONS');

  headers.append('Authorization', 'Basic ' + base64.encode(username + ":" + password));

  fetch(sign_in, {
      //mode: 'no-cors',
      credentials: 'include',
      method: 'POST',
      headers: headers
    })
    .then(response => response.json())
    .then(json => console.log(json))
    .catch(error => console.log('Authorization failed : ' + error.message));
}

我正在使用Chrome浏览器。我也尝试使用Chrome CORS插件,但随后我得到另一个错误消息:

响应中的'Access-Control-Allow-Origin'报头的值 当请求的凭据模式为时,一定不能是通配符'*' “包括”。因此,来源“http://127.0.0.1:3000”是不允许的 访问。对象发起的请求的凭据模式 XMLHttpRequest由withCredentials属性控制。


当前回答

在我的例子中,我必须在所有现有中间件下面添加一个自定义头中间件。我认为一些中间件可能会与Access-Control-Allow-Origin头相冲突,并尝试根据他们的需要来设置它。

所以代码应该是这样的:

app.use(cors());

....all other middleware here

app.use(function (req, res, next) {
  res.header("Access-Control-Allow-Origin", "http://localhost:3000");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  next();
});
...your routes

其他回答

如果您在部署React应用程序netlify时遇到此错误,请使用以下步骤。

步骤1:创建netlify。Toml文件在你的react应用程序的根文件夹。

步骤2:复制粘贴以下代码:

`[[redirects]]
    from = "/cors-proxy/*"
    to = ":splat"
    status = 200
    force = true`

步骤3:以这种方式更新fetch/axios API:

我花了一段时间才想明白。

我犯过很多次这样的错误,正因为如此,我给大家列了一张“清单”。

Enable CORS on your project: If you're using Node.js (by example) you can use: npm install cors; import cors from 'cors'; app.use(cors()); You can manually set the headers like this (if you want it): app.use((req, res, next) => { res.setHeader('Access-Control-Allow-Origin', '*'); res.setHeader('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authortization'); res.setHeader('Acces-Control-Allow-Methods', 'GET, POST, PATCH, DELETE'); Remember to add http:// to your API link in your frontend project, some browsers like Chrome do not accept a request using CORS if the request URL isn't HTTP or HTTPS: http://localhost:3000/api Check if your project is using a proxy.config.js file. See Fixing CORS errors with Angular CLI proxy.

尝试在下面的代码中添加所有这些头文件,在每条路由之前,在你的应用程序中定义,而不是在路由之后

app.use((req, res, next) =>{
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Headers','Origin, X-Requested-With, Content-Type,Accept, Authortization');  
res.setHeader('Acces-Control-Allow-Methods','GET, POST, PATCH, DELETE');

在我的例子中,web服务器阻止了“OPTIONS”方法

检查您的web服务器上的options方法

Apache: https://www ibm.com/support/docview.wss?uid=ibm10735209——01. web层:4.4.6禁用Options方法https://docs.oracle.com/cd/E23943_01/web.1111/e10144/getstart.htm#HSADM174 .单击“确定” nginx: https://medium.com/@hariomvashisth / cors-on-nginx-be38dd0e19df

我用的是webtier / www / webtier /域名(域名)/ config / fmwconfig /组件/羟基/ VCWeb1 / httpd . conf

<IfModule mod_rewrite.c>
  RewriteEngine on
  RewriteCond %{REQUEST_METHOD} ^OPTIONS
  RewriteRule .* . [F]
</IfModule>

改变

<IfModule mod_rewrite.c>
  RewriteEngine off
  RewriteCond %{REQUEST_METHOD} ^OPTIONS
  RewriteRule .* . [F]
</IfModule>

出现问题是因为你在前端添加了以下代码作为请求头:

headers.append('Access-Control-Allow-Origin', 'http://localhost:3000');
headers.append('Access-Control-Allow-Credentials', 'true');

这些头属于响应,而不是请求。所以去掉它们,包括这一行:

headers.append('GET', 'POST', 'OPTIONS');

你的请求有“Content-Type: application/json”,因此触发了所谓的CORS preflight。这导致浏览器使用OPTIONS方法发送请求。详细信息请参见CORS飞行前准备。

因此,在你的后端,你必须通过返回响应头来处理这个预飞行的请求,其中包括:

Access-Control-Allow-Origin : http://localhost:3000
Access-Control-Allow-Credentials : true
Access-Control-Allow-Methods : GET, POST, OPTIONS
Access-Control-Allow-Headers : Origin, Content-Type, Accept

当然,实际的语法取决于后端使用的编程语言。

在你的前端,它应该像这样:

function performSignIn() {
    let headers = new Headers();

    headers.append('Content-Type', 'application/json');
    headers.append('Accept', 'application/json');
    headers.append('Authorization', 'Basic ' + base64.encode(username + ":" +  password));
    headers.append('Origin','http://localhost:3000');

    fetch(sign_in, {
        mode: 'cors',
        credentials: 'include',
        method: 'POST',
        headers: headers
    })
    .then(response => response.json())
    .then(json => console.log(json))
    .catch(error => console.log('Authorization failed: ' + error.message));
}