Angular2-对预检请求的响应未通过访问控制检查:请求的资源上没有“Access-Control-Allow-Origin”标头

时间:2016-08-17 16:47:31

标签: rest angular cors angular2-http

我在Angular 2中调用了一个http帖子。这在post man中工作得很好但是当我在Angular 2中实现这个API调用时,我得到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);
        }
    }

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

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);
        }
    }

2 个答案:

答案 0 :(得分:10)

CORS标题如

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

需要由服务器提供。在客户端添加它们毫无意义。

答案 1 :(得分:3)

当使用非标准标题(json显然被认为是非标准标题)时,会执行飞行前检查以询问是否可以执行所请求的操作(在这种情况下&#39; post&#39;) 。只有服务器可以使用许可标头进行响应。您的回复方式取决于您的服务器语言。在我的webapi2中,我在WebAppConfig

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

对于实时服务器,请注意将localhost ref替换为Web configed列表(或调用方所在的特定位置)。只有在使用身份验证时才需要SupportsCredentials。

为了处理飞行前我向Globals.asax添加了一个方法,该方法只是拦截飞行前的消息并返回足够的数据以便帖子继续前进。

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();
        }
    }

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

请注意,有一些开发作弊。 - 如果你在localhost上运行Internet Explorer(用于开发目的),那么就会忽略大多数其他浏览器所没有的端口,这样可以使事情变得更容易。还有一个针对Chrome的CORS增强功能,可为您添加标题。最后,您会看到许多代码使用&#39; *&#39;返回(允许所有) - 通过一切方式使用它们来使代码工作但在释放之前将这些代码更加严重地锁定。