Angular2-对预检请求的响应未通过访问控制检查:请求的资源上不存在 'Access-Control-Allow-Origin' header

Angular2-Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource

我在 Angular 2 中调用 http post。这在 post man 中工作正常,但是当我在 [=19= 中实现此 API 调用时] 2 我收到 No 'Access-Control-Allow' 错误。这是我的代码

getInspections(): Observable<IInspection[]> {
        if (!this.inspections) {
            let body =JSON.stringify({"Statuses":["Submitted", "Opened"]});
            let headers = new Headers({ 'Content-Type': 'application/json' });

            headers.append('Access-Control-Allow-Origin','*');
            let options = new RequestOptions({ headers: headers });

            return this.http.post(this._baseUrl + '/api/Inspect/ListI',body,options)
                .map((res: Response) => {
                    this.inspections = res.json();
                    return this.inspections;
                })
                .catch(this.handleError);
        }
        else {
            //return cached data
            return this.createObservable(this.inspections);
        }
    }

或者我可以这样做吗?只需传递 header 而不是选项

getInspections(): Observable<IInspection[]> {
        if (!this.inspections) {
            let body =JSON.stringify({"Statuses":["Submitted", "Opened"]});
            let headers = new Headers({ 'Content-Type': 'application/json' });

            //headers.append('Access-Control-Allow-Origin','*');
          //  let options = new RequestOptions({ headers:headers });

            return this.http.post(this._baseUrl + '/api/Inspect/ListI',body,headers)
                .map((res: Response) => {
                    this.inspections = res.json();
                    return this.inspections;
                })
                .catch(this.handleError);
        }
        else {
            //return cached data
            return this.createObservable(this.inspections);
        }
    }

CORS headers 赞

headers.append('Access-Control-Allow-Origin','*');

需要服务器提供。在客户端添加它们是没有意义的。

当使用 non-standard headers(json 显然被认为是 non-standard)时,会执行 pre-flight 检查以询问请求的操作是否(在这种情况下 'post') 可以进行。只有服务器可以响应 headers。您如何回应取决于您的服务器语言。在我的 webapi2 中,我在 WebAppConfig

中实现了 cors
 var cors = new EnableCorsAttribute("http://localhost:3000", "*", "GET, HEAD, OPTIONS, POST, PUT");
        cors.SupportsCredentials = true;
        config.EnableCors(cors);

请注意,对于实时服务器,您可以将本地主机引用替换为网络配置列表(或调用者所在的特定位置)。只有在使用身份验证时才需要 SupportsCredentials。

为了处理 pre-flight 我在 Globals.asax 中添加了一个方法,它只拦截 pre-flight 消息和 returns 足够的数据让 post 继续前进.

protected void Application_BeginRequest()
    {
        if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS")
        {
            var origin = HttpContext.Current.Request.Headers["Origin"];

            Response.Headers.Add("Access-Control-Allow-Origin", origin);
            Response.Headers.Add("Access-Control-Allow-Headers", "content-type, withcredentials, Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers");
            Response.Headers.Add("Access-Control-Allow-Credentials", "true");
            Response.Headers.Add("Access-Control-Allow-Methods", "GET, HEAD, OPTIONS, POST, PUT");

            Response.Flush();
        }
    }

请注意,我在某种程度上通过反射原点来作弊 - 这在生产环境中是不安全的,应该列出特定的服务器,否则你的安全性太松散了。

请注意,存在一些开发作弊行为。 - 如果您在本地主机上的 Internet Explorer 上 运行(出于开发目的),则 ie 会忽略大多数其他浏览器不会忽略的端口,从而使事情变得更容易。 Chrome 还有一个 CORS 增强,它为您添加了 headers。最后你会看到很多代码使用'*'returns(允许所有) - 一定要使用它们来让代码工作但在发布之前更积极地锁定它们。