我曾多次遇到CORS问题,通常可以解决它,但我想通过从MEAN堆栈范式中看到这一点来真正理解。

之前我只是在我的快速服务器中添加了中间件来捕获这些东西,但它看起来像有某种预挂钩,使我的请求出错。

在preflight响应中,Access-Control-Allow-Headers不允许请求报头字段Access-Control-Allow-Headers

我假设我可以这样做:

app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Headers","*")
})

或者等价的,但这似乎不能解决问题。我当然也试过

app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Headers","Access-Control-Allow-Headers")
})

还是不走运。


当前回答

公认的答案是可以的,但我很难理解它。这里有一个简单的例子来说明。

在我的ajax请求我有一个标准的授权头。

$$(document).on('ajaxStart', function(e){
var auth_token = localStorage.getItem(SB_TOKEN_MOBILE);
if( auth_token ) {
    var xhr = e.detail.xhr;

    xhr.setRequestHeader('**Authorization**', 'Bearer ' + auth_token);
}

这段代码产生了问题中的错误。我必须在我的nodejs服务器中添加授权头:

res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type,**Authorization**');

其他回答

当我们为请求定制报头时,会出现这个问题。此请求使用HTTP OPTIONS并包含几个头。

此请求所需的头是Access-Control-Request-Headers,它应该是响应头的一部分,并且应该允许来自所有源的请求。有时在响应头中也需要Content-Type。所以你的响应头应该是这样的

response.header("Access-Control-Allow-Origin", "*"); // allow request from all origin
response.header("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
response.header("Access-Control-Allow-Headers", "Access-Control-Allow-Headers, Origin, X-Requested-With, Content-Type, Accept, Authorization");

当你开始玩自定义请求头,你会得到一个CORS预飞行。这是一个使用HTTP OPTIONS谓词并包含几个头的请求,其中一个是Access-Control-Request-Headers,列出了客户端想要包含在请求中的头。

您需要用适当的CORS报头回复CORS预飞行,以使此工作正常进行。其中之一就是Access-Control-Allow-Headers。该头需要包含与Access-Control-Request-Headers头包含的值相同(或更多)的值。

https://fetch.spec.whatwg.org/#http-cors-protocol将更详细地解释这个设置。

铬:

请求头字段X-Requested-With不被允许 预飞行响应中的Access-Control-Allow-Headers。

对我来说,此错误是由此调用的URL中的尾随空格触发的。

jQuery.getJSON( url, function( response, status, xhr ) {
   ...
}

我在Angular 6中也遇到了同样的问题。我通过使用下面的代码解决了这个问题。在组件中添加代码。ts文件。

import { HttpHeaders } from '@angular/common/http';

headers;

constructor() {
    this.headers = new HttpHeaders();
    this.headers.append('Access-Control-Allow-Headers', 'Authorization');
}

getData() {
    this.http.get(url,this.headers). subscribe (res => {
    // your code here...
})}

如果您试图在请求标头上添加自定义标头,则必须让服务器知道允许发生特定的标头。在过滤请求的类中执行此操作。在下面的例子中,自定义头名称为"type":

public class CorsFilter implements Filter {
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        response.setHeader("Access-Control-Allow-Origin",  request.getHeader("Origin"));
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE,PATCH,OPTIONS");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With, remember-me, Authorization, type ");
        response.setHeader("Access-Control-Expose-Headers","Authorization");
    }
}