我试图用post请求发送文件到我的服务器,但当它发送时,它会导致错误:

Access-Control-Allow-Headers不允许请求报头字段Content-Type。

所以我谷歌了这个错误,并添加了标题:

$http.post($rootScope.URL, {params: arguments}, {headers: {
    "Access-Control-Allow-Origin" : "*",
    "Access-Control-Allow-Methods" : "GET,POST,PUT,DELETE,OPTIONS",
    "Access-Control-Allow-Headers": "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With"
}

然后我得到错误:

Access-Control-Allow-Headers不允许请求报头字段Access-Control-Allow-Origin

所以我谷歌了一下,我能找到的唯一类似的问题是提供了一半的答案,然后关闭为跑题。我应该添加/删除什么头?


当前回答

我也有同样的问题。在jQuery文档中,我发现:

对于跨域请求,将内容类型设置为application/x-www-form-urlencoded、multipart/form-data或text/plain以外的任何类型将触发浏览器向服务器发送preflight OPTIONS请求。

因此,尽管服务器允许跨源请求,但不允许Access-Control-Allow-Headers,它将抛出错误。默认情况下,angular的内容类型是application/json,它试图发送一个OPTION请求。尝试覆盖angular默认头或允许访问控制允许头在服务器端。下面是一个角度的例子:

$http.post(url, data, {
    headers : {
        'Content-Type' : 'application/x-www-form-urlencoded; charset=UTF-8'
    }
});

其他回答

如果这对任何人都有帮助,(即使这有点可怜,因为我们必须只允许用于开发目的)这里有一个Java解决方案,因为我遇到了同样的问题。 [编辑]不要使用通配符*,因为它是一个糟糕的解决方案,如果你真的需要在本地工作,请使用localhost。

public class SimpleCORSFilter implements Filter {

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
    HttpServletResponse response = (HttpServletResponse) res;
    response.setHeader("Access-Control-Allow-Origin", "my-authorized-proxy-or-domain");
    response.setHeader("Access-Control-Allow-Methods", "POST, GET");
    response.setHeader("Access-Control-Max-Age", "3600");
    response.setHeader("Access-Control-Allow-Headers", "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
    chain.doFilter(req, res);
}

public void init(FilterConfig filterConfig) {}

public void destroy() {}

}

如果你正在使用localhost和PHP来解决这个问题:

header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Headers: Content-Type'); 

从您的前端使用:

{headers: {"Content-Type": "application/json"}}

boom没有更多的问题来自localhost!

您试图设置的头是响应头。它们必须在响应中由您发出请求的服务器提供。

在客户端上没有设置它们的位置。如果可以由需要权限的站点而不是拥有数据的站点授予权限,那么使用一种授予权限的方法就毫无意义了。

以下是我使用nodejs的工作:

xServer.use(function(req, res, next) {
  res.setHeader("Access-Control-Allow-Origin", 'http://localhost:8080');
  res.setHeader('Access-Control-Allow-Methods', 'POST,GET,OPTIONS,PUT,DELETE');
  res.setHeader('Access-Control-Allow-Headers', 'Content-Type,Accept');

  next();
});

在我的例子中,我将几个参数作为@HeaderParam接收到一个web服务方法中。

这些参数必须在你的CORS过滤器中声明:

@Provider
public class CORSFilter implements ContainerResponseFilter {

    @Override
    public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {

        MultivaluedMap<String, Object> headers = responseContext.getHeaders();

        headers.add("Access-Control-Allow-Origin", "*");
        ...
        headers.add("Access-Control-Allow-Headers", 
        /*
         * name of the @HeaderParam("name") must be declared here (raw String):
         */
        "name", ...);
        headers.add("Access-Control-Allow-Credentials", "true");
        headers.add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");   
    }
}