我试图用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

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


当前回答

服务器(POST请求被发送到的服务器)需要在其响应中包含Access-Control-Allow-Headers头(等等)。将它们放在客户端的请求中是没有效果的。您应该删除“Access-Control-Allow-…”从你的POST请求。

这是因为由服务器来指定它是否接受跨源请求(以及它是否允许Content-Type请求头等等)——客户机不能自己决定给定的服务器是否应该允许CORS。

请求者(web浏览器)可以通过发送一个“OPTIONS”请求(即不是你想要的“POST”或“GET”请求)来“preflight”测试服务器的同源策略。如果对'OPTIONS'请求的响应包含'Access-Control-Allow-…'头,允许你的请求使用的头,来源或方法,然后请求者/浏览器将发送你的'POST'或'GET'请求。

(模糊的注释:)Access-Control-Allow-…使用值”,而不是列出特定的来源、头文件或允许的方法。然而,我使用的旧Android WebView客户端不尊重“通配符,需要在OPTIONS请求的响应中Access-Control-Allow-Headers头中列出的特定头。

其他回答

对我来说,我在web.config中有通配符“*”Access-Control-Allow-Headers:

<add name="Access-Control-Allow-Headers" value="*" />

这个解决方案适用于大多数导航器,但不适用于Safari或IE

结果证明,解决方案是手动添加所有自定义头到web.config:

<system.webServer>
    <httpProtocol>
        <customHeaders>
            <add name="Access-Control-Allow-Origin" value="https://somedomain.com" />
            <add name="Access-Control-Allow-Methods" value="GET,POST,OPTIONS,PUT,DELETE" />
            <add name="Access-Control-Allow-Headers" value="custom-header1, custome-header2, custome-header3" />
        </customHeaders>
    </httpProtocol>
<system.webServer>

如果这对任何人都有帮助,(即使这有点可怜,因为我们必须只允许用于开发目的)这里有一个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() {}

}

我也有同样的问题。在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'
    }
});

服务器(POST请求发送到的服务器)需要在响应中包含Content-Type报头。

下面是一个典型的报头列表,包括一个自定义的“X_ACCESS_TOKEN”报头:

"X-ACCESS_TOKEN", "Access-Control-Allow-Origin", "Authorization", "Origin", "x-requested-with", "Content-Type", "Content-Range", "Content-Disposition", "Content-Description"

这就是你的http server需要为你发送请求的web服务器配置的东西。

你可能还想让你的服务器人员公开“Content-Length”报头。

他会认为这是一个跨源资源共享(CORS)请求,并且应该理解进行这些服务器配置的含义。

详情见:

http://www.w3.org/TR/cors/ http://enable-cors.org/

服务器(POST请求被发送到的服务器)需要在其响应中包含Access-Control-Allow-Headers头(等等)。将它们放在客户端的请求中是没有效果的。您应该删除“Access-Control-Allow-…”从你的POST请求。

这是因为由服务器来指定它是否接受跨源请求(以及它是否允许Content-Type请求头等等)——客户机不能自己决定给定的服务器是否应该允许CORS。

请求者(web浏览器)可以通过发送一个“OPTIONS”请求(即不是你想要的“POST”或“GET”请求)来“preflight”测试服务器的同源策略。如果对'OPTIONS'请求的响应包含'Access-Control-Allow-…'头,允许你的请求使用的头,来源或方法,然后请求者/浏览器将发送你的'POST'或'GET'请求。

(模糊的注释:)Access-Control-Allow-…使用值”,而不是列出特定的来源、头文件或允许的方法。然而,我使用的旧Android WebView客户端不尊重“通配符,需要在OPTIONS请求的响应中Access-Control-Allow-Headers头中列出的特定头。